ELF(X4H14 (444  S S (p} { {  /usr/lib/ld.so.1GNUah[b0=O:Q*(^6U5})|t'Ks_!I V3x/pPM\i"<#rBH 8{2qWN.~ELoA9ZY > &lcT1FanCJX?`D@f kzS,d4vG+uy; g-%wR]mej$7 %{ .z D| J<H PH"U`\8d lpyht"(H 8x"8| h8lX!(0X47 L@S"_h"j((u x(`X\(dd| "h "hX/HlF M"TX]bH $ X4("x$( " "<&P ""8"8" " "xLX " h " "( " (*8 "?F"LHSZ"a("z(L"xL"HH"8""h""4H") XL"0"| 0} !8 "!p(44} : "BI"N,V@"]8} !i<q"})  P X8} 0} Xp d x"<| %| 1 __gmon_start__/usr/lib/libtk8.0.so_DYNAMIC_GLOBAL_OFFSET_TABLE__init_finifreestrlenstrncmpsprintfTk_ParseArgv__strtol_internalTk_GetUidmallocstrcpymemcpymemsetTcl_GlobalEvalTcl_AddErrorInforeallocstrcmp__ctype_bmemcmpstrchrTk_DefineBitmapTcl_CreateInterpstrncpyTcl_DoOneEventstrcatTk_GetNumMainWindowsprintfstrncasecmpstrcasecmpTcl_SetVarTcl_GetVarTcl_EvalTcl_CreateCommandTk_MainWindowTk_InitTcl_SetVar2Tcl_VarEvalTkCreateXEventSourceTcl_CreateFileHandlerTcl_DeleteFileHandlersignalselectTcl_CreateTimerHandlerTcl_DeleteTimerHandlersscanfgetuidgetpwuidtimestrstr/usr/lib/libtcl8.0.sofprintfabortstderr__xstat__errno_locationexitTcl_Initgetsockoptsetsockoptstrerrorfcntlreadwritecloserecvsendinet_ntoasocketbindlistenconnectinet_addrgethostbynameacceptrenamechmodgetenvexecvpgetpidgettimeofdaylibX11.so.6calloc__umodsi3sleepstrncatXSetIOErrorHandlerfwritefopenfgetsfclosefreadsetlocalelibc.so.6longjmprandomgetsperrorfeof_IO_2_1_stdin_sys_nerrrecvfromputenv__sigsetjmpstdinsendmsgstrtokforksrand48strdupsys_errlistlrand48gethostnamesrandomfileno_IO_stdin_used__libc_start_main_sys_errlist_sys_nerrlibm.so.6libdl.so.2_startlibresolv.so.2dn_expandres_mkquery__res_sendfflush_etext_edata__bss_start_end{ 7{ | | c0} v4} h8} u$ 7$z ^(z ,z  0z 4z *8z C뚍KH嚍K H嚍KH嚍K,H嚍KH囍K嚍K0HK@⛍K+# K$@⛝K+ K(@⛍K  K(@⛝K, K(@⛍K, K4@⛝K # K⛍K # K@⛝K # K@⛍K # K @⛝K # K0@⛍K K⛝K. K@⛍K. K0@⛝K K$@⛍K 뛝KIP*5P㛝K NK@D5 ᛍKH8뚍K$H $ I 08B $ H07B㚝K,IdKIP㛝K6KH`㛍KH-K B,PMK @Dp 0g뚍K$H0Y y뛍K=K 0C,0 SʂK@᚝K$I |ꛍKHS`P (K@+07뚍K$H $ I08BHNK@D PJ@⚍K4H@噍K4H⛝KI[K8PEP噝K8I⛍K}K0 +K$ B⚝K I07K(ꚍKHH뚝KI4P#LK @D`=K(0C0囝KI=K 0>0 +K$ B⚍K H0,O# K @ <{뚝K0I@ @(r뚍K0H@#LK@DPKP @FPK0H#KA⛝KI K0$ <@HKHf뚝KI(P K0I#KA⛍KH O#LK@D  MK.x.p=K 0R8 \0 RK0I@0嚍K0H嚝K0I4 0HT \ \ \ H"0嚝K0I0嚍K0H40"000囝K嚝K0Ib K@뚝K0I=K 0R K$@PMK(@DPB K(A52PK,IY7#\K0PE mK`F.#LK@D $ F B .>@]K(PE@}K(pG@ @0T;K80C0=K80C00=K<0C00=K(0C 0#0囍K 0KP.ꚝKI뚍KHP ⚍K(H#0囍K 0;OP $ ؑ\ <H S``P #LK0@D D MK0@D囝KI d뚍KH 0뚝KI 0M#LK0@D # 뚍K0HX <H뚝K0I0 00뚍K0H#LK@DPK0HᛝKI KꚍK0H#KA⛝KI gO뚍K0H0 P,K0H0V뚍K0H0 #LK0@D #\KPE mK`F.  .|ᛍKH(0S # K@P 0aPS  2S0SSL08 $K %00S $0$̐  <400S2 00S|2$ H$KdX00SS#LK @D`=K40C0囍KH=K 0>0 +K$ B⚝K I0 H(ꚍKH뚝KIWP#LK @D`=K40C0囝KI=K 0>0 +K$ B⚍K H0L# K @P 뚝K0IY <L뚍K0H000(A뚝K0I#LK@DP P K0I#KA⛍KH HGꚝKI>뚍KHlP K0H#KA⛝KI L0@04 $K K,T &@8@H<T#LK @D #\KPE mK. { w.sK0HX l=K 0R6 X0 RK0I<0嚍K0H嚝K0I4  0ꀐ`h \ \ \ "0嚝K0I0嚍K0H40T"000bMK@D뚝K0IM뚝KI bKI⚍K8H=K0C00K8I⛍KH=K80C00=K40C0 0噍K$H⚝K@10T aQ!@0TA1p!1p10s QxA|UXp L1P!@00<K0C""( 20; 01wK8H0wK(L0wmK `Fw=K 0C  B wK(L l 00SwmK(`F` wK8H>K0C0wK0 wmK `F w=K 0C0&E@)A^0"PwK(H wK8L>K0C0wmK<`F``.=K 0C 0>0 wK H w=K 0C0H@$AT1fKPwK8LNK @DwmK<`F P wK8H0B wK8L0;W<p0000NK,PwmK<`F VEP < H̐$   KwKK0C0>K 0C 0>0 .K BwmK`F0A3@0jP&NK @DwK(H>K0C0wKK 0C 0>0 .K BwmK`F0E ꀐ<@8@ HK @X W<Tp00(ONK @D-P  (PK AwKK0>K 0C0>K 0C0` `>K0C$0>K(0>K,00>K0C40>K 0C80.=K 0C:ꀐ<@ HT`   wKH2wK4L !00200w=K0C0 0p20>K0>K 0C0>K 0C0` `>K0C$0>K(0>K,00>K0C40.=K 0C80>K 0C<0! K@wK Lw=K 0C wmK`F0@10wK0HwKH\X' 10S# wK$L0wmK$`F!KAEP`wK,L`wK$H0<1000wmK$`FwmK,`F`X0&0SwK,HX"W ! K@@9000 Rp0p4 00 00p40p| 000wK$L`jwK$He0wmK$`F00`0Z鐡  @ \ \ \  -LAM`pPH001KFK@ GOKP  00lL  -LWMMW|KpGWK☀HWKI WKL0W|KpGWK⤐IW|KpG2P$KP#@KWKL"$pKPWK⠀H"$KPWKLl"xp$pKPWK⠀HH"oP$KPWKL$"f0$pKPWK⠀H"]$KPWKL!T$pKPWK⠀H!K$KPWKL!B$pKPWK⠀Hp!9$KPWKLL!0W|KpG{K K 1$0C"Kppp XK-K4 B {Kp1K \W|KpGW|KpGp00S S> 00S0zWKHWK☀H00SS!p00Sh0hiWKIWK☐I 00B00000000000\ $ ĕ 0WKLpWKH 0ppp10S WKHWKⰐI W|KpGWKH WK☐IWKⰐIW|KpGW|KpGWK☐I WP WKL\00S3 0 .WK☐IWK✐I  9P W|KpG 1P WKHIWKL `P pW00S 0\ 4$ PPWKL0lW|KpGc`8 8`# MK4@DM WKI`8 8`# MK4@D? KP pW|KpG WK⸐I{KW|KpGKWKI{KW|KpGKWKȐI{KW|KpGKL KH {KW|KpG3$KW|KpGpW}WKH`0a0CS=h\{zxtw$~4lxy0}v@|wX`WK⠐I` 7`PHr0S <8WK⠀HWK✀H hppWK⠀H`WK⤀H` `P 0S9 W|KpG<W|KpG`W|KpG`WK̀H `PPq0S Pq@WK⤀HWK✀H hppWK⬀HT`WK⨀H` `P0S RW|KpGW|KpGpgIW|KpGtW|KpGp WWKH1$0CX `P<0S D,,WKLpWKLl#X\ 0H`|ĖWKL 1$0CW|KpGXKWKI0iWKLppcpWK⼀H XȒ0SŸW|KpGp1$0C0 l`P|0S xtWK⨐IWK✐I iWK⼐I 1$0CWKLppp0 WKH0hWKI cYW|KpGpA$@D( 9`P0S (oWKⴐI 1$0C(WKĐI YX0SMLqXHWKĀH1$0C `P 0S1 WKL 1$0CW|KpGpg|"W|KpGp1$0CWKĀHWK⸐I Yt0Shp|WK⸀H!$I0x0WWK☐I0I0c$0W|KpG2@X0S `P,0S2 TW|KpGpg)\ 4HXLhԎ$ ̘ W|KpGp0gWKH cWKL\W|KpGpW 30S XWKⰀHWKԐIWKL\ 20SFW|KpGWKԀHWK⤐IY |20S x3WKLW|KpGTBPP ,20S42 , B( 0  0 0< 08 0, 00 0@ 0 0 0WK⠀HlWK⠐I 0WKLDW|KpG 0L0SH0L0 L0S00SF0WAL< P 00S0K L 03L0S/ RLK@DV\KPE=K40C0L 0P K4@]WKЀH\ $< T$ `dtЙ 0\2 $K WKL {KWK⸐I \mW|KpGWKLpWKDIWKH pWKLpWK‐IWKHK Ap$0Gx@WK܀H WKI0AW K@UWKLp0S 3U8<0 0WKLp03U8<0 0WKLpSp!pKAW\KPEK bpKW|KpG ZWKIHK R<< N4qWKH!0WKI K ?W|KpG 8ܐWKL 0 K4@WP }20S2 "$0I$K0!$ !rWKAx"0P d[`20ST2 L2WLK@DP"0 2WKI@ pp 0!01 "40"( q!0 K4@W(, ,+DP ,P $P P  0 0<0 ( ( < ,( ,,( 0 R`0`4 0 00`40`p 000(0< 00 8 ,0 \ ` <@̐<8\ \ l  -L0@T0 p`P{P0@%0 R40S 0 4004 R00S4 000PP4 00000 408 T\ \  p-L@d00TX`PP@0T@800T,`$P@0Tq\  \  p p-LP@ `tTp)000C S`Ň@ p-LPPp @ `cTp)0]S[S $S`@ 0-LPP0 @PT0)0]S[S $S00S0Y @\ $  p-LP@0@T 4`Pp 0@000Tp\ \  -L MM@`Pp, PP0  (90 () 000 "() 000 "() 0 0,$() 0Sp0ppK@ @T!@00 00W00C100001i)i,)$I @ `$L @ u`W9 |A$IKA j`$L0  b 0`0S$I$ V00`00S S  0 0$0C)C000CX:0 0$ C009B00`IOK,|PvU K@ 0EP@PIK,o< t| p-LP@0@T 4`Pp 0@000Tp\ \  -LM( `4 , P|p0q P@U p04 00T@00 0041p\0C100000pp1lx,xlĠ',4 (  `4qW( @   `0`00CS$ 0`0S S  0 00CX:0  0`@0 y0 0  r`0q 0 0`I_K,0|tB@T  0zP=@P,逞 t| -LMpP1B11P10UtalAP0UPT10UHa@AzP0UP@W `0 S`0 S 0S 10C@P Q0"QK0P00@&U T10C@@K@d0|LP0S D@10CX AP10C0S007 $   \  \  ОԎ 0-LGM0(1 I?K0J?K0l+0PPX0EOK r U00,   E?K0鰚  4h$ Dh -LMP@d _\P# LY@pK44#4303`Kl0  #T jP eP `P4b 00@K i 0 P +|0K` TPVPS PP MpPJ`@P 2P 2 P 1P 1P 1@DT񟗜ꐲX0`A101 00p0 `l1$0P(P\pA@1041 00p0 `$1$0P(P \@000 00p0 `0$0P(PHp@ 0#PR `0   Dhhhh   ` h hhhhi i 0 R ]0 1Q`0P!\@H T 410)s11110 `1A PP){ P 0 stKy@  00 0U 0E  c00e0pcW djxj$ jjjP|0% [|L0 0p<@PD <l ܏  kkk$ kkkll l,l -LMMM @Pp,cW *0 0;.Q pUP 0 tP20K 000 0_ pc KM.K B}> p\Y 4[c(#(c4"4#4K4[c(#(c4"4#4K4[c(#(c4"4#4KMKI 4[#2!00k]KPEp0Wa@T  *0@0PTPp0Wp0WDMKH@0S T D 00@0PTP P@aT# 0S  .000`0@0PT@F0 SP0`  E0`P@p0WMK@H740=000ܔ0| , 0lOP3 \>C00P"X P D P 0 }P  wP  qP2 @@PP2 :`U0#03P0S 00WxY00 00Wn@00Y g@:PP# 00X[@;PP 00\  p\  0e;PP 00X2@X +\00 \00\00\00\00\;PP00 0P  \  & CP\009|P\00/X P\ "$ ,nPnXn`nhnpnxnnnnnnh P\ \ ^ [U@@Tnn -LM( `p }P@  v0P@@0 S0 S  h0P@/PP   PP 00V |00Vu@ PPv 00X P0 P000@0 S0 S :PP;PPY I00Y% >!00Y 7@;PP \  0M00\  A@;PP00 0P \  +` PP U<08( nnnnnnno$ o -LMp ! `W7 `L1Q@0S*4!1$ 00SPP 0 S < 7  0&@ +T `cVڌJp0 K P\2X!,K00K  8#8#4#4#8#4#3K  P@P᠐ @PK 4KP  L 0KH0 D@ tP1 @Q0Stl1@ ! X11 K1 RT2$@ 010K 1 RT2$A |12|1j?K0K.K0P sT  0@ Tp\9L o @o`oooo$ ppkl l l  po00 90 0 0@\ H `<1q P R `cVpK0?K0?K0?K 0@@ G?K 3S0 3 $3S0$3 KP (3S0(3 $3SGK  %OKP pGK #(3 GK  0 $ r -L -L -LM0  L -L 0(r4r -LM@ 0?00 0鰟 \  -L@7 N8r -L(00"(@ 8r -LM@K .K "$ P0UnK,`?A,`8P0U@.K000SPFt0P<`h@!\0 L00eP&U n $ wn wwwww < \m m  -LM`pP PK`@0 L0D 04 }00  0v $ wwww -Ld0 R X0T0bLP8p@`A X,0PUn  wx m l  -LgMM @dS0SXP#00H3PP0DS, pT00pSp T 00rS006 BNK@D+`:`P 2 똖- 00| APPH2d @X20TLrQP20"@20T100 P Wr W P:00 K P/P!1 $K 00/05KWK@ :@PP`  0;`00p 0 (1$KⳐH@P I0$K 8#8#4#4#8#4#00CK &00 0_L6P <PI0\ 5 o $o (o x$ dx|xxxl pcxxx,y8yHy+Ip34 `|d pPA$@D K\p1X!$ B83\40X4p$ A$@D\!Xp\ 1 0$ C2\40X4p!$ B2\4<0X4pEK CKAP  L$ =KH4 Dt P sR ph"00@\20SP2a$`FpV 826 K 1P RT 515K 1P RT \62\6=K0C0K-K0PJ T"V  & =K 0C0i>KP|&R EK 004 01 @, +2a111R 00cܐ0+0 P000[WAPT00S }P00 000嘖02PyXyxyyyy (o ,yy$o  o yz Ptt t0Th P @@ H0G !04( zz z0zdzlzyz p-L@`P0P  0 pz{ p-L@d` 0H00P 0,0  `0p@{ o   -L 00(o  -L -Lxqt@pd 0PX^T0 4@< P (0 $   D{L{$ P{d{ -L0,o  -LMpP@$K 6 000``$0K0p 0~ =0 0#000f R00R0S 00@b4o  8o  -L 0000300#13001200#22002100#31000000C"#B!" "  "00Q  0-LhMP0S |@KX, e$PK@ 000( 000  0S0,o   -LM@`$K pP 0  0 a00 0 0S0S000(@00$0K0 00o   -L, -L0000000000 0#EgܺvT2 -LPp`0?!00S0502050>0@@`V: *1-@@?0S:@ d 0-LMP@K 0!? 7R8 bx b4K  X 0C3C 5C  XP hQ I*%B?*B00TP0霈159<  PP `fjF   `P 靈!%,@ 0 0LP0`kI37;%>  8P pgyV0HY5C:C;C   dP h]04/8:  PP 靈'Q- 0 0H2C6C7C   TP h>b269  @P 靈*0F5C:C;C   `k6G:C?C0C  XP pgy0E4Z8;   DP hZ26;<  0P 靈 F1&B+B0 0\P0`k & "8P pgx'H+B/B0' 0#0脇)38 " 0 2 20h@    ,, 020202 $ { p-L`x0@T P P "R22"R 2 20T20JpBTp  -LBM41@`,,P`BTV P0@pW”l8,8lĠ#,…”l8,8lĠ#,…”l8,8lĠ#,…, ,_BpWNKD# 800PP!0  {{{ -LZM1PIOK_/KP l!q@P們 H10S U RU!00pP1ÃW;*1ĉ c`Ub0` RC@Ai8)8i#)”l8,8lĠ#,†i8)8i#),-\ (T0H D0|@PpℑW:{ { ,# {{{ -LM ! `Pp P P P |餑@PT 0S P0P PPV`00 00U00C1000001i)i,) 10ऑ(gK P  "  0S0$  00 0 ! ! 00 ! 0S pS  100 p00CW:100   101 p 100 pWژ ( \101 夑( 01 {{{  agKHPeK _OK!c_K 50!0#0 -=101 fK``I_K|t@bT !021P@P[ || -LMP `D@P | KPpP 0P0P AP`P APPPE@K? NKz$0I hS0QP\  ᭿ 0 | { -LpM`㫿@㨿 匀KPK0pK+ 2/ 7 K 00/P`V (0$ 0 | -LMR@KO 0-L@P.p 0 p-LP@\`00S ܿPp@T@0*S @Tp|o  -Lp` PCP00R0S! @0Ġ R0TP Ġ R0TP?0 00,à?0 00,à?0 00,à?0 00P00R0Sr r =00A=00A  p  p-LM  `Pp0?CQ7@PP姾@pK K 0PP/P00@pVUUU | -L(M8 < @ L0 ,pK4KD H   i8)8i#) R:H)< R*i8)8i#) R:3 0R 0R  00 003L3 97L53@?N0:@95@51@?L@08@94@50@1#5@@06@92@52@1#7@ 05@:0@6#4@28@ 03@:1@6#6@2:@01@:#3@67@2#<@<:86410=<884400:;6713#308;4703#506;17#3#'04;07#53901:#367!XY X0P`0 20L"100'965&# <90/<#! 2#40 ( 810#"$ ;30%"# <20*y   y Tx   640"") @010$"( 850$* 0#10*"% 7#90!R00'%0 <:0""! 510*& 140& <50)! 3#50*" 810+  6#50 # 380   940'"' 4#;0/0"R00`0#1PVY3P`3 42L>"00'965&# <90/<#! 2#40 ( 810#"$ ;30%"# <20*  640"") @010$"( 850$* 0#10*"% 7#90!R00'%0 <:0""! 510*& 140& <50)! 3#50*" 810+  6#50 # 380   940'"' 4#;0/0"R00`0,!1PV_1 X00LY0S 0 xR *@P0000@P AR:0LX Y 0000000 i8)8i#) R:@婑@ LY X%,;J Tx y y  X%L4CJ<`@Y @ 98531#1@0:96511#309:5602#407:3612#606;2723#704;743#90<#1854#:0<#3874S 97̃53?Ό0:9551?̌ 09:4624 07:26#22606;17#33704;07#53903<18#601<38#8P3@Yăs?0 0#ഓ!?0 0#ࠓ1!?0 0#1!?0 0#p1!?0 0#X1!?0 0#@1!?0!1 =2 0#1 @P00$4 33(& 8 60,) < 90 < <$"! 4 10(" 8 10,% < 40 ( 0 70#% 3 #60'"  !;00+  030 # 3#:0# * 7#70' ' ;#40+ $ 0#10 R00"!0 2 10&$ 6 40*' : 70 * 0 :0""# 2 30& 6 00*# : 20 & 0 50!' 1 #80%$ 5 #50)! 9 #20@ ! @0 10/3/3%") 5 90)"& y Pq Pp Pw Pv Pu Pt Ps Pr  0#30 R00`@Y@ :F <`@Y/ 0 0#0 0 " @98531#1@0:96511#309:5602#407:3612#606;2723#704;743#90<#1854#:0<#3874S97̃53?Ό0:9551?̌ 09:4624 07:26#22606;17#33704;07#53903<18#6$*01<38#8P3@Yă?0 0#ഓ!?0 0#ࠓ1!?0 0#1!?0 0#p1!?0 0#X1!?0 0#@1!?0!(1 =2 0#1 @P00$4 33(& 8 60,) < 90 < <$"! 4 10(" 8 10,% < 40 ( 0 70#% 3 #60'"  !;00+  030 # 3#:0# * 7#70' ' ;#40+ $ 0#10 R00"!0 2 10&$ 6 40*' : 70 * 0 :0""# 2 30& 6 00*# : 20 & 0 50!' 1 #80%$ 5 #50)! 9 #20@ ! @0 10/3/3%") 5 90)"& y Pp Pw Pv Pu Pt Ps Pr Pq  0#30 R000000`@Y@ /^<`@YZ 0D000@ 98531#1@0:96511#309:5602#407:3612#606;2723#704;743#90<#1854#:0<#3874S 97̃53?Ό0:9551?̌ 09:4624 07:26#22606;17#33704;07#53903<18#601<38#8P3@Yă?0 0#ഓ!?0 0#ࠓ1!?0 0#1!?0 0#p1!?0 0#X1!?0 0#@1!?0!(1 =2 0#1 @P00$4 33(& 8 60,) < 90 < <$"! 4 10(" 8 10,% < 40 ( 0 70#% 3 #60'"  !;00+  030 # 3#:0# * 7#70' ' ;#40+ $ 0#10 R00"!0 2 10&$ 6 40*' : 70 * 0 :0""# 2 30& 6 00*# : 20 & 0 50!' 1 #80%$ 5 #50)! 9 #20@ ! @0 10/3/3%") 5 90)"& y Pp Pw Pv Pu Pt Ps Pr Pq  0#30 R000 0#00 0#0D0000`@Y@ (<`@Y~ @ 98531#1@0:96511#309:5602#407:3612#606;2723#704;743#90<#1854#:0<#3874S 97̃53?Ό0:9551?̌ 09:4624 07:26#22606;17#33704;07#53903<18#601<38#8P3@Yă?0 0#ഓ!?0 0#ࠓ1!?0 0#1!?0 0#p1!?0 0#X1!?0 0#@1!?0!(1 =2 0#1 @P00$4 33(& 8 60,) < 90 < <$"! 4 10(" 8 10,% < 40 ( 0 70#% 3 #60'"  !;00+  030 # 3#:0# * 7#70' ' ;#40+ $ 0#10 R00"!0 2 10&$ 6 40*' : 70 * 0 :0""# 2 30& 6 00*# : 20 & 0 50!' 1 #80%$ 5 #50)! 9 #20@ ! @0 10/3/3%") 5 90)"& y Pp Pw Pv Pu Pt Ps Pr Pq  0#30 R000 0#00 0#00000`@Y@ .<`@Y 0D000@ 98531#1@0:96511#309:5602#407:3612#606;2723#704;743#90<#1854#:0<#3874S 97̃53?Ό0:9551?̌ 09:4624 07:26#22606;17#33704;07#53903<18#601<38#8P3@Yă?0 0#ഓ!?0 0#ࠓ1!?0 0#1!?0 0#p1!?0 0#X1!?0 0#@1!?0!(1 =2 0#1 @P00$4 33(& 8 60,) < 90 < <$"! 4 10(" 8 10,% < 40 ( 0 70#% 3 #60'"  !;00+  030 # 3#:0# * 7#70' ' ;#40+ $ 0#10 R00"!0 2 10&$ 6 40*' : 70 * 0 :0""# 2 30& 6 00*# : 20 & 0 50!' 1 #80%$ 5 #50)! 9 #20@ ! @0 10/3/3%") 5 90)"& y Pp Pw Pv Pu Pt Ps Pr Pq  0#30 R000 0#00 0#0D0000`@Y@ (<`@Y @ 98531#1@0:96511#309:5602#407:3612#606;2723#704;743#90<#1854#:0<#3874S 97̃53?Ό0:9551?̌ 09:4624 07:26#22606;17#33704;07#53903<18#601<38#8P3@Yă?0 0#ഓ!?0 0#ࠓ1!?0 0#1!?0 0#p1!?0 0#X1!?0 0#@1!?0!(1 =2 0#1 @P00$4 33(& 8 60,) < 90 < <$"! 4 10(" 8 10,% < 40 ( 0 70#% 3 #60'"  !;00+  030 # 3#:0# * 7#70' ' ;#40+ $ 0#10 R00"!0 2 10&$ 6 40*' : 70 * 0 :0""# 2 30& 6 00*# : 20 & 0 50!' 1 #80%$ 5 #50)! 9 #20@ ! @0 10/3/3%") 5 90)"& y Pp Pw Pv Pu Pt Ps Pr Pq  0#30 R000 0#00 0#0`@Y@ 2Y 0000 i8)8i#) R:8 i8)8i#) R:H)< R*i8)8i#) R: 0-LVMt t000l0PP[OKeTbl KP0@0S(0$儱0 @| D| L| p-L`@ұPͱPp @ 00 00D失PPp +0ጱ@00ᣱp`|@|h| -LQM`p(! @ 00$1KK@ ㅱVJKI/KP 00$1KT 00T  l0  \00I?K0 $(,048<(!0l|@| p|x| -L`p@P  S \000 000@  K@<0i)i,)0 00 0#00 鴚  -Lp@EP000  ` &&0A@ `@FႱ -LAM@p` PP Z( ,P( G_K`PH ( K0( ( 0,0@| -LSM4MP2@t@KsKO tAKK@ 㻰pSmK `Fp S}K pG `$0FPC R K$@.㤰R K4@.㟰F K@ 㚰F K@ 㕰E K4@+㐰NK@D+㊰R K<@~ 0ቯS}K 0ႯSmK`F 0yS}KpG+.]K>SmK`Fp`&h`oP jP>NK@DḰ0F-K BS}KpG0@P 0x| 0<c@ @(^@ SmK`F PPG( 0֯l||||||| &P !P5NK@Do0F-K BS}KpG0o@P "0㫯<!@ @(2FKL0#40 SmK`F P L@"0㎯F K@4 㔯 K$@$.㏯1 副뜳S}KpG`p'xp ͯP6ȯP1>0K@FKASmK`F R=K40C@Pb |\!0UY<ɮ0 00îD1FKL "$ S}KpG 0PW  呯P<匯P7>0K@FKASmK`F R=K40C @P& l 0Y<㍮0 00㇮F K@L  S}KpG |||||||||@|||F K@ R K4@.SmK `F JS}K pGp p;P ]Kp F K@h ߮R K4@X.ڮ | @Ԯ8!P (PHE]K4PEK@ 0SmK`FҲS}KpG`p'xp|K$pGSmK`Fp.FMK@D a(S}KpGpp>0SmK`F S}KpG0( SmK`F NN||@|} }$}||ήP xɮP<E]K4PEK@ 0CS}KpGSmK`Fp`&h`lK$`FS}KpG`.㖮FMK@D 㐮(㼭SmK`F``>0S}KpG SmK`F0 S}KpG ~KpGSmK`Fp׮ t`KS}KpG`H00 00S}KpGppR=K<0C0 010]?K000F]KPEP` `$0$0 0(0FMK@D,@p0p(040  4 fKC`PK-L0t#.K0㳥A?z z  ā؁؀4 -LM`4"  Pp1@0@K/K 0AKKK@ 0BKK@ @100K 0#100#Kl 00K` 00S0c#^K8ݤ@P ,ȣ10 K0L 4 0 P*嵣Τ@0 K08 㬤p 㧤@P  ˣp@ 㚤P 0p吣d d<_z z 4 x 0؁Dt -L M`Pp2@AKsK@ wBKK@ qBKK@ ki@200K 0ጤ200-K| 0ᄤKp ဤ@00 00P`P0 00 4XP0 00000-nK 5PP  1/K0ᦤ4-Kx KjLTL 0 L0P "ᘤnKpPP L0 0K KN8p 00P |)  0000c0S0000 00#100 0S S  00CR:00HF@0</K08z z  4 D-M8 000@00 # Ѝ -LM400 0 r0@0 C z  -L -L| tickcrossuparrowdownarrowphonephone1phone2phone3phone4maileyeaudiowbwwwtextunknownclockucltoolsbullet0bullet1broadcastmeetingtestsbroadcastsmeetingstestsecuresdrbus recv errorWarning: 2K local conf bus message truncated 224.1.127.255connectDest Address problem setsockopt ttlttl: %d bus sendLCB/1.0sdr instance interface visible OK, mapping i/f envDISPLAYTTL problem on LCB: message ignored someone else Unknown LCB message type received LCB/1.0 sdr instance %u %s %s %sError %daudiowhiteboardvideo0%x%x Unexpected packet. Dumping... Buffer length: %d %c<<< socketsocket fd too large (%d) Binding socket %d to address/port %s/%d bindAddress: %x, Port: %d setsockopt - IP_ADD_MEMBERSHIPConnecting socket %d to address/port %s/%d connectDest Address problem setsockopt ttlttl: %d cryptsymmrn=%lu %lu %lu %s %u %u %s %s %s %s %s %s %sk%lu %lu %lu %s %u %u %sNOAUTHnoneNOENCk=trustedtrustworthyTRUSTWORTHYintegrityINTEGRITYfailedFAILEDsuccessSUCCESSnoenc12desSdr internal error: tried to copy too large a buffer: %d pgpcpgpx509stateThe session contained an x509 digital signature, the signature has not been checked DES Encryption: Success Key: Key name: Sdr internal error: data length of %d x509%denc_pgp_cleanup enc_pkcs7_cleanup v=cx50authtype is wrong in sap_headernoauthcompresion is setsdr:corrupted cache file: %s CLC_NUMERIC=Cgethostname failed! gethostbyname failed (hostname='%s'! /etc/resolv.confdomain.noname-s-d1-no_gui-cli-logguiGUINO_GUIlogTRUEFALSEdebug10224.2.127.254224.0.1.75Failed to open SIP TCP socket load_cache_entryload_from_cachewrite_cacheSdr: %s build_interface firstreshow_sessions [set showwhich]recv errorWarning: 2K announcement truncated unacceptably short announcement received and ignored announcement with version>1 received and ignored Sdr internal error: encstatus_p failed to be set %s:%u: failed assertion `%s' ../src/sd_listen.caddata->sapenc_p->txt_data != NULLuntrustedset %s(%d) [clock format %u -format {%%d %%b %%y %%H:%%M %%Z}]Announcement doesn't end in LF - will try to fix it up Illegal end-of-string character present - removed! No session name field 0 0 No end to version name Error decoding session Failure at byte %ld Error decoding description Error decoding URI Error decoding originator Too many email fields Error decoding email address Too many phones (!) Error decoding channel Too many bandwidth fields Error decoding bandwidth Too many times Error decoding time Too many repeats Too many keys Error decoding key :No keytag found with key clearCan't handle %s keytag Mediakey too long - it has been truncated Sdr: too many media Error decoding media Error decoding attribute Remaining text: %s<<< sdr: too many attributes to fit in available space decoding cache data! Error decoding cache data Warqning: unknown option - >%s< Error decoding unknown No originator field No description field reset_media%s asym_cur_keyidsess_auth_typesess_auth_statussess_auth_messageenc_asym_cur_keyidsess_enc_typesess_enc_statussess_enc_messagetrustrecvkeysessiondescNo channel field received! Unacceptably long channel field received %s %s %s%u %utfromttostarttime(%d)%uendtime(%d)repeat(%d,%d)rctr(%d)Illegal infinite session with multiple time fields tfrom(0)tto(0)rctr(0)starttime(0)endtime(0)multicastUnacceptably long originator field received %s %s %s %s %s %screatormodtimecreatetimecreateaddr%s%s%sget_aid %sadvertidsourceheardfromset timeheard [clock format %u -format {%%d %%b %%y %%H:%%M %%Z}]uriphone(%d)email(%d)bw(%d)keysessvarsUnacceptably long media field received %s %d %s %smediavarsportprotofmtmediattlmedialayersmediaaddrmediakeyset_mediaset_media[%d] for session %s: %s recvttlrecvsap_addrrecvsap_portadd_to_listadd_to_list failed for session %s: %s INsdr: expected network type IN, got %s IP4sdr: expected address type IP4, got %s sending %s sending encrypted session ----- sending ad to sock %d, ttl %d WARNING: received key containing Tcl special chars something is wrong advertid is not set in writing file .tmpwsomething is wrong writing encryption too many args to command to be run! Failed to execute %s ؟П̟ğ|tld\TLDplugtutpluginsnode15node14node13node12node11node10node9node8node7node6node5node4node3node2node1sdrchangesbugstoolsmboneabout

Frequently Asked Questions (FAQ) on the Multicast Backbone (MBONE)

Steve Casner, casner@isi.edu, 22-Dec-94

*** This file is ftp://ftp.isi.edu/mbone/faq.txt ***
*** Corrections and Additions Requested ***

Note: This file has badly needed updating since the 6-May-93 version. Some of the most glaring errors have been fixed here, but more rewriting is required. It is also intended that this text form and an HTML form will be generated from a common source. Some other sources of info are:
http://www.research.att.com/mbone-faq.html
ftp://taurus.cs.nps.navy.mil/pub/mbmg/mbone.html
ftp://genome-ftp.stanford.edu/pub/mbone/mbone-connect
http://www.cl.cam.ac.uk/mbone/
http://www.eit.com/techinfo/mbone/mbone.html

What is the MBONE?

The MBONE is an outgrowth of the first two IETF "audiocast" experiments in which live audio and video were multicast from the IETF meeting site to destinations around the world. The idea is to construct a semi-permanent IP multicast testbed to carry the IETF transmissions and support continued experimentation between meetings. This is a cooperative, volunteer effort.

The MBONE is a virtual network. It is layered on top of portions of the physical Internet to support routing of IP multicast packets since that function has not yet been integrated into many production routers. The network is composed of islands that can directly support IP multicast, such as multicast LANs like Ethernet, linked by virtual point-to-point links called "tunnels". The tunnel endpoints are typically workstation-class machines having operating system support for IP multicast and running the "mrouted" multicast routing daemon.

How do IP multicast tunnels work?

IP multicast packets are encapsulated for transmission through tunnels, so that they look like normal unicast datagrams to intervening routers and subnets. A multicast router that wants to send a multicast packet across a tunnel will prepend another IP header, set the destination address in the new header to be the unicast address of the multicast router at the other end of the tunnel, and set the IP protocol field in the new header to be 4 (which means the next protocol is IP). The multicast router at the other end of the tunnel receives the packet, strips off the encapsulating IP header, and forwards the packet as appropriate.

Previous versions of the IP multicast software (before March 1993) used a different method of encapsulation based on an IP Loose Source and Record Route option. This method remains an option in the new software for backward compatibility with nodes that have not been upgraded. In this mode, the multicast router modifies the packet by appending an IP LSRR option to the packet's IP header. The multicast destination address is moved into the source route, and the unicast address of the router at the far end of the tunnel is placed in the IP Destination Address field. The presence of IP options, including LSRR, may cause modern router hardware to divert the tunnel packets through a slower software processing path, causing poor performance. Therefore, use of the new software and the IP encapsulation method is strongly encouraged.

What is the topology of the MBONE?

We anticipate that within a continent, the MBONE topology will be a combination of mesh and star: the backbone and regional (or mid-level) networks will be linked by a mesh of tunnels among mrouted machines located primarily at interconnection points of the backbones and regionals. Some redundant tunnels may be configured with higher metrics for robustness. Then each regional network will have a star hierarchy hanging off its node of the mesh to fan out and connect to all the customer networks that want to participate.

Between continents there will probably be only one or two tunnels, preferably terminating at the closest point on the MBONE mesh. In the US, this may be on the Ethernets at the two FIXes (Federal Internet eXchanges) in California and Maryland. But since the FIXes are fairly busy, it will be important to minimize the number of tunnels that cross them. This may be accomplished using IP multicast directly (rather than tunnels) to connect several multicast routers on the FIX Ethernet.

How is the MBONE topology going to be set up and coordinated?

The primary reason we set up the MBONE e-mail lists (see below) was to coordinate the top levels of the topology (the mesh of links among the backbones and regionals). This must be a cooperative project combining knowledge distributed among the participants, somewhat like Usenet. The goal is to avoid loading any one individual with the responsibility of designing and managing the whole topology, though perhaps it will be necessary to periodically review the topology to see if corrections are required.

The intent is that when a new regional network wants to join in, they will make a request on the appropriate MBONE list, then the participants at "close" nodes will answer and cooperate in setting up the ends of the appropriate tunnels. To keep fanout down, sometimes this will mean breaking an existing tunnel to inserting a new node, so three sites will have to work together to set up the tunnels.

To know which nodes are "close" will require knowledge of both the MBONE logical map and the underlying physical network topology, for example, the physical T3 NSFnet backbone topology map combined with the network providers' own knowledge of their local topology.

Within a regional network, the network's own staff can independently manage the tunnel fanout hierarchy in conjunction with end-user participants. New end-user networks should contact the network provider directly, rather than the MBONE list, to get connected.

What is the anticipated traffic level?

The traffic anticipated during IETF multicasts is 100-300Kb/s, so 500Kb/s seems like a reasonable design bandwidth. Between IETF meetings, most of the time there will probably be no audio or video traffic, though some of the background session/control traffic may be present. A guess at the peak level of experimental use might be 5 simultaneous voice conversations (64Kb/s each). Clearly, with enough simultaneous conversations, we could exceed any bandwidth number, but 500Kb/s seems reasonable for planning.

Note that the design bandwidth must be multiplied by the number of tunnels passing over any given link since each tunnel carries a separate copy of each packet. This is why the fanout of each mrouted node should be no more than 5-10 and the topology should be designed so that at most 1 or 2 tunnels flow over any T1 line.

While most MBONE nodes should connect with lines of at least T1 speed, it will be possible to carry restricted traffic over slower speed lines. Each tunnel has an associated threshold against which the packet's IP time-to-live (TTL) value is compared. By convention in the IETF multicasts, higher bandwidth sources such as video transmit with a smaller TTL so they can be blocked while lower bandwidth sources such as compressed audio are allowed through.

Why should I (a network provider) participate?

To allow your customers to participate in IETF audiocasts and other experiments in packet audio/video, and to gain experience with IP multicasting for a relatively low cost.

What technical facilities and equipment are required for a network provider to join the MBONE?

Each network-provider participant in the MBONE provides one or more IP multicast routers to connect with tunnels to other participants and to customers. The multicast routers are typically separate from a network's production routers since most production routers don't yet support IP multicast. Most sites use workstations running the mrouted program, but the experimental MOSPF software for Proteon routers is an alternative (see MOSPF question below).

It is best if the workstations can be dedicated to the multicast routing function to avoid interference from other activities and so there will be no qualms about installing kernel patches or new code releases on short notice. Since most MBONE nodes other than endpoints will have at least three tunnels, and each tunnel carries a separate (unicast) copy of each packet, it is also useful, though not required, to have multiple network interfaces on the workstation so it can be installed parallel to the unicast router for those sites with configurations like this:

		   +----------+
		   | Backbone |
		   |   Node   |
		   +----------+
			|
    ------------------------------------------ External DMZ Ethernet
	     |               |
	+----------+    +----------+
	|  Router  |    |  mrouted |
	+----------+    +----------+
	     |               |
    ------------------------------------------ Internal DMZ Ethernet

(The "DMZ" Ethernets borrow that military term to describe their role as interface points between networks and machines controlled by different entities.) This configuration allows the mrouted machine to connect with tunnels to other regional networks over the external DMZ and the physical backbone network, and connect with tunnels to the lower-level mrouted machines over the internal DMZ, thereby splitting the load of the replicated packets. (The mrouted machine would not do any unicast forwarding.)

Note that end-user sites may participate with as little as one workstation that runs the packet audio and video software and has a tunnel to a network-provider node.

What skills are needed to participate and how much time might have to be devoted to this?

The person supporting a network's participation in the MBONE should have the skills of a network engineer, but a fairly small percentage of that person's time should be required. Activities requiring this skill level would be choosing a topology for multicast distribution with in the provider's network and analyzing traffic flow when performance problems are identified.

To set up and run an mrouted machine will require the knowledge to build and install operating system kernels. If you would like to use a hardware platform other than those currently supported, then you might also contribute some software implementation skills!

We will depend on participants to read mail on the appropriate mbone mailing list and respond to requests from new networks that want to join and are "nearby" to coordinate the installation of new tunnel links. Similarly, when customers of the network provider make requests for their campus nets or end systems to be connected to the MBONE, new tunnel links will need to be added from the network provider's multicast routers to the end systems (unless the whole network runs MOSPF).

Part of the resources that should be committed to participate would be for operations staff to be aware of the role of the multicast routers and the nature of multicast traffic, and to be prepared to disable multicast forwarding if excessive traffic is found to be causing trouble. The potential problem is that any site hooked into the MBONE could transmit packets that cover the whole MBONE, so if it became popular as a "chat line", all available bandwidth could be consumed. Steve Deering plans to implement multicast route pruning so that packets only flow over those links necessary to reach active receivers; this will reduce the traffic level. This problem should be manageable through the same measures we already depend upon for stable operation of the Internet, but MBONE participants should be aware of it.

Which workstation platforms can support the mrouted program?

The most convenient platform is a Sun SPARCstation simply because that is the machine used for mrouted development. An older machine (such as a SPARC-1 or IPC) will provide satisfactory performance as long as the tunnel fanout is kept in the 5-10 range. The platforms for which software is available:
    Machines             Operating Systems       Network Interfaces
    --------             -----------------       ------------------
    Sun SPARC            SunOS 4.1.1,2,3         ie, le, lo
    Vax or Microvax      4.3+ or 4.3-tahoe       de, qe, lo
    Decstation 3100,5000 Ultrix 3.1c, 4.1, 4.2a  ln, se, lo
    Silicon Graphics     All ship with multicast
There is an interested group at DEC that may get the software running on newer DEC systems with Ultrix and OSF/1. Also, some people have asked about support for the RS-6000 and AIX or other platforms. Those interested could use the mbone list to coordinate collaboration on porting the software to these platforms!

An alternative to running mrouted is to run the experimental MOSPF software in a Proteon router (see MOSPF question below).

Where can I get the IP multicast software and mrouted program?

The IP multicast software is available by anonymous FTP from the vmtp-ip directory on host gregorio.stanford.edu. Here's a snapshot of the files:
	ipmulti-pmax31c.tar
	ipmulti-sunos41x.tar.Z	    Binaries & patches for SunOS 4.1.1,2,3
	ipmulticast-ultrix4.1.patch
	ipmulticast-ultrix4.2a-binary.tar
	ipmulticast-ultrix4.2a.patch
	ipmulticast.README	    [** Warning: out of date **]
	ipmulticast.tar.Z	    Sources for BSD

### Release 3.3 of the SunOS kernel multicast extensions was made in
### late August, but was not put on gregorio like previous releases.
### Instead, it is on parcftp.xerox.com, directory pub/net-research,
### file ipmulti3.3-sunos413x.tar.Z  This release has multicast
### pruning and several other major improvements over previous
### releases, so upgrading is encouraged.
You don't need kernel sources to add multicast support. Included in the distributions are files (sources or binaries, depending upon the system) to modify your BSD, SunOS, or Ultrix kernel to support IP multicast, including the mrouted program and special multicast versions of ping and netstat.

Silicon Graphics includes IP multicast as a standard part of their operating system. The mrouted executable and ip_mroute kernel module are not installed by default; you must install the eoe2.sw.ipgate subsystem and "autoconfig" the kernel to be able to act as a multicast router. In the IRIX 4.0.x release, there is a bug in the kernel code that handles multicast tunnels; an unsupported fix is available via anonymous ftp from sgi.com in the sgi/ipmcast directory. See the README there for details on installing it.

IP multicast is also included in all Solaris 2 releases. Solaris 2.3 out of the box supports the non-pruning version of mrouted (mrouted version 2.0-2.2), but mrouted is not included with Solaris so you must fetch the mrouted sources from the multicast software distribution and compile them. Solaris 2.2 requires patches to run mrouted, available from ftp.uoregon.edu in the directory /pub/Solaris2.x/src/MBONE/Solaris2.x/Kernel.

IP multicast is supported in BSD 4.4.

The most common problem encountered when running this software is with hosts that respond incorrectly to IP multicasts. These responses typically take the form of ICMP network unreachable, redirect, or time-exceeded error messages, which are a waste of bandwidth and can cause an error in the packet send operation executed by a multicast source. The result may be dropouts in an audio or video stream. These responses are in violation of the current IP specification and, with luck, will disappear over time.

What documentation is available?

Documentation on the IP multicast software is included in the distribution on gregorio.stanford.edu (ipmulticast.README). RFC1112 specifies the "Host Extensions for IP Multicasting".

Multicast routing algorithms are described in the paper "Multicast Routing in Internetworks and Extended LANs" by S. Deering, in the Proceedings of the ACM SIGCOMM '88 Conference.

There is an article in the June 1992 ConneXions about the first IETF audiocast from San Diego, and a later version of that article is in the July 1992 ACM SIGCOMM CCR. A reprint of the latter article is available by anonymous FTP from venera.isi.edu in the file pub/ietf-audiocast-article.ps. There is no article yet about later IETF audio/videocasts.

Where can I get a map of the MBONE?

The most recent "complete" map of the MBONE is available in two Postscript files are available on parcftp.xerox.com:
        /pub/net-research/mbone-map-{big,small}.ps
The small one fits on one page but is hard to read, and the big one is four pages that have to be taped together for viewing. This map was produced from topology information collected automatically from all MBONE nodes that respond to remote queries for mapping information (some are running ancient versions of mrouted that do not respond, and some are hidden by firewalls or routing boundaries). Pavel Curtis at Xerox PARC has added the mechanisms to automatically collect the map data and produce the map. (Thanks also to Paul Zawada of NCSA who manually produced an earlier map of the MBONE.)

The MBONE is now large enough that it is hard to show all nodes and links on one graph. To give a higher level view of the MBONE, there is another map that shows only the major links and nodes in a roughly geographical representation that was created manually by Steve Casner. It is available from ftp.isi.edu:

	mbone/mbone-topology.ps

What is DVMRP?

DVMRP is the Distance Vector Multicast Routing Protocol; it is the routing protocol implemented by the mrouted program. An earlier version of DVMRP is specified in RFC-1075. However, the version implemented in mrouted is quite a bit different from what is specified in that RFC (different packet format, different tunnel format, additional packet types, and more). It maintains topological knowledge via a distance-vector routing protocol (like RIP, described in RFC-1058), upon which it implements a multicast forwarding algorithm called Truncated Reverse Path Broadcasting. DVMRP suffers from the well-known scaling problems of any distance-vector routing protocol.

What is MOSPF?

MOSPF is the IP multicast extension to the OSPF routing protocol, currently an Internet Draft. John Moy has implemented MOSPF for the Proteon router. A network of routers running MOSPF can forward IP multicast packets directly, sending no more than one copy over any link, and without the need for any tunnels. This is how IP multicasting within a domain is supposed to work.

Can MOSPF and DVMRP interoperate?

At the Boston IETF, John Moy agreed to add support for DVMRP to his MOSPF implementation. He hopes to have this completed "well in advance of the next IETF". When it is finished, you will be able to set up a DVMRP tunnel from an mrouted to Proteon a router, glueing together the DVMRP with MOSPF domains (the MOSPF domains will look pretty like ethernets to the multicast topology).

The advantages to linking DVMRP with MOSPF are: fewer configured tunnels, and less multicast traffic on the links inside the MOSPF domain. There are also a couple potential drawbacks: increasing the size of DVMRP routing messages, and increasing the number of external routes in the OSPF systems. However, it should be possible to alleviated these drawbacks by configuring area address ranges and by judicious use of MOSPF default routing.

How do I join the MBONE?

STEP 1: If you are an end-user site (e.g., a campus), please contact your network provider. If your network provider is not participating in the MBONE, you can arrange to connect to some nearby point that is on the MBONE, but it is far better to encourage your network provider to participate to avoid overloading links with duplicate tunnels to separate end nodes. Below is a list of some network providers who are participating in the MBONE, but this list is likely not to be complete.
	AlterNet	mbone-request@uunet.uu.net
	CA*net		canet-eng@canet.ca
	CERFnet		mbone@cerf.net
	CICNet		mbone@cic.net
	CONCERT		mbone@concert.net
	Cornell		swb@nr-tech.cit.cornell.edu
	JvNCnet		multicast@jvnc.net
	Los Nettos	prue@isi.edu
	NCAR		mbone@ncar.ucar.edu
	NCSAnet		mbone@cic.net
	NEARnet		nearnet-eng@nic.near.net
	OARnet		oarnet-mbone@oar.net
	ONet		onet-eng@onet.on.ca
	PSCnet		pscnet-admin@psc.edu
	PSInet		mbone@nisc.psi.net
	SESQUINET	mbone@sesqui.net
	SDSCnet		mbone@sdsc.edu
	Sprintlink	mbone@sprintlink.net
	SURAnet		multicast@sura.net
	UNINETT		mbone-no@uninett.no
If you are a network povider, send a message to the -request address of the mailing list for your country to be added to that list for purposes of coordinating setup of tunnels, etc:
	Australia:	mbone-oz-request@internode.com.au
	Austria:	mbone-at-request@noc.aco.net
	Canada:	 	canet-mbone-request@canet.ca
	Denmark:	mbone-request@daimi.aau.dk
	France:		mbone-fr-request@inria.fr
	Germany:	mbone-de-request@informatik.uni-erlangen.de
	Italy:		mbone-it-request@nis.garr.it
	Japan:		mbone-jp-request@wide.ad.jp
	Korea:		mbone-korea-request@cosmos.kaist.ac.kr
	Netherlands:	mbone-nl-request@nic.surfnet.nl
	New Zealand:	mbone-nz-request@waikato.ac.nz
	Singapore:	mbone-sg-request@technet.sg
	UK:		mbone-uk-request@cs.ucl.ac.uk
If your country is not listed, send your request to the appropriate regional sublist:
	Europe:		mbone-eu-request@sics.se
	N. America:	mbone-na-request@isi.edu
	other:		mbone-request@isi.edu
These lists are primarily aimed at network providers who would be the top level of the MBONE organizational and topological hierarchy. The mailing list is also a hierarchy; mbone@isi.edu forwards to the regional lists, then those lists include expanders for network providers and other institutions. Mail of general interest should be sent to mbone@isi.edu, while regional topology questions should be sent to the appropriate regional list.

Individual networks may also want to set up their own lists for their customers to request connection of campus mrouted machines to the network's mrouted machines. Some that have done so were listed above.

STEP 2: Set up an mrouted machine, build a kernel with IP multicast extensions added, and install the kernel and mrouted; or, install MOSPF software in a Proteon router.

STEP 3: Send a message to the mbone list for your region asking to hook in, then coordinate with existing nodes to join the tunnel topology.

How is a tunnel configured?

Mrouted automatically configures itself to forward on all multicast-capable interfaces, i.e. interfaces that have the IFF_MULTICAST flag set (excluding the loopback "interface"), and it finds other mrouteds directly reachable via those interfaces. To override the default configuration, or to add tunnel links to other mrouteds, configuration commands may be placed in /etc/mrouted.conf. There are two types of configuration command:
        phyint    [disable]   [metric ] [threshold ]

        tunnel   [metric ] [threshold ]
The phyint command can be used to disable multicast routing on the physical interface identified by local IP address , or to associate a non-default metric or threshold with the specified physical interface. Phyint commands should precede tunnel commands.

The tunnel command can be used to establish a tunnel link between local IP address and remote IP address , and to associate a non-default metric or threshold with that tunnel. The tunnel must be set up in the mrouted.conf files of both ends before it will be used. The keyword "srcrt" can be added just before the keyword "metric" to choose source routing for the tunnel if necessary because the other end has not yet upgraded to use IP encapsulation. Upgrading is highly encouraged. If the methods don't match at the two ends, the tunnel will appear to be up according to mrouted typeouts, but no multicast packets will flow.

The metric is the "cost" associated with sending a datagram on the given interface or tunnel; it may be used to influence the choice of routes. The metric defaults to 1. Metrics should be kept as small as possible, because mrouted cannot route along paths with a sum of metrics greater than 31. It is recommended that the metric of all links be set to 1 unless you are specifically trying to force traffic to take another path. On such a "backup tunnel", the metric should be the sum of metrics on primary path + 1.

The threshold is the minimum IP time-to-live required for a multicast datagram to be forwarded to the given interface or tunnel. It is used to control the scope of multicast datagrams. (The TTL of forwarded packets is only compared to the threshold, it is not decremented by the threshold. Every multicast router decrements the TTL by 1.) The default threshold is 1.

Since the multicast routing protocol implemented by mrouted does not yet prune the multicast delivery trees based on group membership (it does something called "truncated broadcast", in which it prunes only the leaf subnets off the broadcast trees), we instead use a kludge known as "TTL thresholds" to prevent multicasts from traveling along unwanted branches. This is NOT the way IP multicast is supposed to work; MOSPF does it right, and mrouted will do it right some day.

Before the November 1992 IETF we established the following thresholds. The "TTL" column specifies the originating IP time-to-live value to be used by each application. The "thresh" column specifies the mrouted threshold required to permit passage of packets from the corresponding application, as well as packets from all applications above it in the table:

						TTL     thresh
						---     ------
	IETF chan 1 low-rate GSM audio		255	 224
	IETF chan 2 low-rate GSM audio		223	 192
	IETF chan 1 PCM audio			191	 160
	IETF chan 2 PCM audio			159	 128
	IETF chan 1 video			127	  96
	IETF chan 2 video			 95	  64
	local event audio			 63	  32
	local event video			 31	   1
It is suggested that a threshold of 128 be used initially, and then raise it to 160 or 192 only if the 64 Kb/s voice is excessive (GSM voice is about 18 Kb/s), or lower it to 64 to allow video to be transmitted to the tunnel.

Mrouted will not initiate execution if it has fewer than two enabled vifs, where a vif (virtual interface) is either a physical multicast-capable interface or a tunnel. It will log a warning if all of its vifs are tunnels, based on the reasoning that such an mrouted configuration would be better replaced by more direct tunnels (i.e., eliminate the middle man). However, to create a hierarchical fanout for the MBONE, we will have mrouted configurations that consist only of tunnels.

Once you have edited the mrouted.conf file, you must run mrouted as root. See ipmulticast.README for more information.

Have there been any movements towards productizing any of this?

The network infrastructure will require resource management mechanisms to provide low delay service to real-time applications on any significant scale. That will take a few years. Until that time, product-level robustness won't be possible. However, vendors are certainly interested in these applications, and products may be targeted initially to LAN operation.

IP multicast host extensions are being added to some vendors' operating systems. That's one of the first steps. Proteon has announced IP multicast support in their routers. No network provider is offering production IP multicast service yet.

What hardware platforms support the audio and video applications?

Most of the applications have been ported to the DEC 5000, DEC Alpha, HP 9000/700, SGI Indy and Indigo, and Sun SPARCstation. Some applications are also supported on IBM RS/6000 and on Intel 486 platforms running BSD UNIX. No additional hardware is required to receive audio and video on those systems that have audio built in because the rest is done in software. To send audio requires a microphone; to send video requires a camera and video capture device which are only built-in on a few of the systems. For example, the VideoPix card has been used on the SPARC, but is no longer for sale. The newer SunVideo card is supported under Solaris 2.x, but there is no device driver for SunOS 4.1.x (at least not yet). See the descriptions of video applications below for a list of the capture boards supported by each program.

For the camera, any camcorder with a video output will do. The wide-angle range is most important for monitor-top mounting. There is also a small (about 2x2x5 inches) monochrome CCD camera suitable for desktop video conference applications available for around $200 from Howard Enterprises Inc, 545 Calles San Pablo, Camarillo, CA 93102, phone 805-383-7444. Subjectively, it seems to give a picture somewhat less crisp than a typical camcorder, but sufficient for 320x240 resolution software video algorithms. There is also a color model and an infrared one for low light, with an IR LED for illumination.

What operating system support is required?

You can run the audio and video applications point-to-point between two hosts using normal unicast addresses and routing, but to conference with multiple hosts, each host must run an operating system kernel with IP multicast support. IP multicast invokes Ethernet multicast to reach multiple hosts on the same subnet; to link multiple local subnets or to connect to the MBONE you need a multicast router as described above.

IP multicast is included in the standard IRIX kernels for SGI machines, in Solaris 2.3 and later, and in OSF/1 2.0. You can pick up free IP multicast software and add it to AIX 3.2, HP-UX, SunOS 4.1.x and Ultrix as described above. For PC machines running DOS or Windows, IP multicast support is included in the current release of the PCTCP package from FTP Software, but the application programs are still in development. No IP multicast support is available yet for NeXT or Macintosh.

The IP multicast kernel software releases for AIX, HP-UX, SunOS, and Ultrix include a patch for the module in_pcb.c. This patch allows demultiplexing of separate multicast addresses so that multiple copies of vat can be run for different conferences at the same time.

If you run a SunOS 4.1.x kernel, you should make sure that the kernel audio buffer size variable is patched from the standard value of 1024 to be 160 decimal to match the audio packet size for minimum delay. The IP multicast software release includes patched versions of the audio driver modules, but if for some reason you can't use them, you can use adb to patch the kernel as shown below. These instructions are for SunOS 4.1.1 and 4.1.2; change the variable name to amd_bsize for 4.1.3, or Dbri_recv_bsize for the SPARC 10:

	adb -k -w /vmunix /dev/mem
	audio_79C30_bsize/W 0t160	(to patch the running kernel)
	audio_79C30_bsize?W 0t160	(to patch kernel file on disk)
	
If the buffer size is incorrect, there will be bad breakup when sound from two sites gets mixed for playback.

What is the data rate produced by the audio and video applications?

The audio coding provided by the built-in audio hardware on most systems produces 64 Kb/s PCM audio, which consumes 68-78 Kb/s on the network with packet overhead. The audio applications implement software compression for reduced data rates (36 Kb/s ADPCM, 17 Kb/s GSM, and 9 Kb/s LPC including overhead).

For the slow-frame-rate video prevalent on the MBONE, the compression, decompression and display are all done in software. The data rate is typically 25-128 Kb/s, with the maximum established by a bandwidth limit slider. Higher data rates may be used with a small TTL to keep the traffic within the local area. Support for hardware compression boards is in development.

Where can I get the audio applications?

The most popular application on the MBONE is the LBL audio tool "vat". A beta release of vat is available by anonymous FTP from ftp.ee.lbl.gov in the directory conferencing/vat where you will find tar files for the various systems supported:
	decalpha-vat.tar.Z	DEC Alpha
	decmips-vat.tar.Z	DEC 5000
	hp-vat.tar.Z		HP 9000/700
	i386-vat.tar.Z		intel 386/486 BSD
	sgi-vat.tar.Z		SGI Indy, Indigo
	sun-vat.dyn.tar.Z	SPARC, dynamic libraries
	sun-vat.tar.Z		SPARC, static libraries
Included in the vat tar files are a binary and a manual entry. The authors, Van Jacobson and Steve McCanne, say the source will be released "soon". Either SPARC version will run SunOS 4.1.x. The dynamically linked version works better than the statically linked version on Solaris 2 since it will adhere to the name service policy that the user has configured. There is a problem with vat in unicast mode on Solaris 2.3 (it works fine in multicast mode). This will be fixed in the next Solaris release. In the mean time, there is a work around for the problem available by FTP from playground.sun.com in the tar file pub/solaris2/unicast-vat-workaround.tar.

MBone software for Digital Alpha workstations running OSF/1 V2.0 and newer is available at

	http://chocolate.pa.dec.com/mbone
	ftp://chocolate.pa.dec.com/mbone
In addition, a beta release of both binary and source for the UMass audio tool NEVOT, written by Henning Schulzrinne, is available by anonymous FTP from gaia.cs.umass.edu in the pub/hgschulz/nevot directory (the filename may change from version to version). NEVOT runs on the SPARCstation and on the SGI Indigo and Indy. NEVOT supports both the vat protocol and RTP protocol.

What hardware and software is required to receive video?

The video we used for the July 1992 IETF was the DVC (desktop video conferencing) program from BBN, written by Paul Milazzo and Bob Clements. This program has since become a product, called PictureWindow. Contact picwin-sales@bbn.com for more information.

For the November 1992 IETF and several events since then, we have used two other programs. The first is the "nv" (network video) program from Ron Frederick at Xerox PARC, available from parcftp.xerox.com in the file pub/net-research/nv.tar.Z. An 8-bit visual is recommended to see the full image resolution, but nv also implements dithering of the image for display on 1-bit visuals (monochrome displays). Shared memory will be used if present for reduced processor load, but display to remote X servers is also possible. On the SPARCstation, the VideoPix card is required to originate video. Sources are to available, as are binary versions for the SGI Indigo and DEC 5000 platforms.

Also available from INRIA is the IVS program written by Thierry Turletti and Christian Huitema. It uses a more sophisticated compression algorithm, a software implementation of the H.261 standard. It produces a lower data rate, but because of the processing demands the frame rate is much lower and the delay higher. System requirements: SUN SPARCstation or SGI Indigo, video grabber (VideoPix Card for SPARCstations), video camera, X-Windows with Motif or Tk toolkit. Binaries and sources are available for anonymous ftp from avahi.inria.fr in the file pub/videoconference/ivs.tar.Z or ivs_binary_sparc.tar.Z.

SDR BUGS/UNFINISHED LIST

There are many little things on the to-do list. The main big things are:

- on Windows when an announcement is received whilst scrolling the list
  of sessions this will cause sdr to crash. Also on Win95 (not NT) when
  quitting from sdr an error message regarding a page fault pops up - 
  sdr has exited okay and written the cache files but the window pops up.
- end times of SIP sessions are bogus
- changing session type should reposition the session in the main window
  but doesn't.
- Two-way SIP sessions should be unicast not multicast.
- Only minimal SIP functionality implemented
- client/server split not yet finished
- built-in plugins can't be switched off
   - can (sort-of be overridden, but is ugly)
- sdr hangs in WWW browser during DNS lookup
- adding new admin scope zones should be automated
   + this is awaiting the client/server split
- doesn't handle SDPv2 repeat times with units "M" and "Y"
- repeat time offset lists are only handled in limited cases
- doesn't handle SDPv2 "i" fields in media
- internationalistion very patchy
- WWW browser should cache files
- Doesn't check the version field before updating entries - inefficient
- Doesn't do proper IPRA multicast address allocation
   + awaiting simulation results
- Doesn't cope properly with DNS names for multicast groups



Things which need looking at in SDR 2.5.6

A) General

1) Windows problem - sdr crashes when it receives a session and the scrollbar is being moved. 2) Create session - the final window doesn't show any session details 3) Create session - doesn't disappear when you click Accept FIXED EPW 26/Aug/98 4) Modify session doesn't work 5) Roy had problem: > when changing the scope from admin to ttl: > invalid command name ".new.f3.rr.f.r4" > while executing > ".new.f3.rr.f.r4 invoke" > ("default" arm line 3) Then when changing the ttl from 15 to world: > can't read "win": no such variable > while executing > "$win.f3.rr.f.e configure -state normal" > (procedure "disable_scope_entry" line 2) And when went back to admin scope - choose and configure media gave: > can't read "fmtlayers(html..)": no such element in array > while executing > "return $fmtlayers($media.$proto.$fmt)" 6) PC version of sdr didn't need Tcl environment but now it does ? Shrimp version doesn't need tcl ? 7) Quitting on Windows 95 gives a very ugly "this program crashed" message. 8) conflict with random and srandom prototypes 9) SIP always listens on 5060 so if sdr dies on windows you have to log off - is it supposed to just listen on port 5060 meaning you can only have one person running sdr on each machine ?

B) Encryption etc

1) Even if you don't want to use PGP you still get asked where your keyring is. This is fixed now. The first time it asks you for PGP Keyring location just do cancel. (GOLI) 2) On Solaris the authentication sometimes gets lost (we think this is due to a new session arriving whilst the previous one hasn't completed the authentication/encryption routines). 3) On PC - window asking where keyrings are pops up quite often - should be just once. This is fixed (Goli) 4) Louise got the message, after a window appeared asking for her PGPPATH (she doesn't use PGP): The same as 1 > pygmalion.ucaclxc.9:16%The Decryption didnot produce any message 0 > [1] Segmentation fault sdr (core dumped) Donot know what the problem is (GOLI) 5) Andreas got message: > "the decryption did not produce any message > window name "pgpinfo" already exists in parent This is fixed. ON PC the home should be set to c:\sdr (GOLI) 6) Some key generation problems on windows - Alberto said: From the key generation panel, trying to generate pgp keys, an error is generated since sdr call 'xterm' obviously not available on window platform. Trying to generate an x509 key, the file generated contain an error since 'uuencode' is called and not present on the windows platform. The key generation only work on Unix not PC (GOLI) 7) Bill fenner gets a core dump on SunOS when trying to create an authenticated session - problem seems to be in check_authentication: > #1 0x41b94 in check_authentication (auth_p=0x1e61e8, authinfo=0x1e61ea "0", > data=0xefffb7b8 " '", data_len=325, auth_len=156, > asym_keyid=0xefffb780 "", irand=51221, > authmessage=0xefffb580 "The message is signed using keyid 0x7F01BC09") > at ../src/pgp_crypt.c:253 > 253 memcpy(authmessage,auth_message,messagelen); > > I bet the problem is: > > (gdb) p messagelen > $6 = 65280 > > I dunno how memory for auth_message is supposed to be allocated, and I > can't think of why auth_message would always be a well-terminated > string, but I think the calculation of messagelen combined with the > (lack of?) allocation of memory for auth_message is causing this dump. > > Shouldn't this be Tcl_SetVar() instead of depending on tcl returning > a pointer to the actual data storage and overwriting it with memcpy? Could not compile on Sun4 to find the problem. (GOLI) 8) putlogfile in the tcl files seems to cause problems (Peter Koch) (Goli made this change - "puts -> putlogfile" to solve some problems on windows) Change putlogfile to puts for debuging This is changed now(GOLI) 9) I think there are a number of memory problems as sdr will be fine for a while then the bounds checking will stop it. Not sure where these problems are yet but I think some are in the PGP code - I haven't even tried the PKCS#7 code yet. 10) Alberto Casu: - Choose PGP encryption, prompted for pgppath, no keys displayed - If select PGP encryption then change to DES -> error when select a group key as it is still trying to read the pgp keyfile (he thinks) error: can't read "user_id(pgp,0)": no such element in array while executing "set user_id(pgp,enc_cur_key_sel) $user_id(pgp,$pgpkey)" (command bound to event) - also if specify pgp enc/auth and don't select key (it doesn't display any anyway) get the error "Cannot open c:\mbone\sdr\63920.sig". The file "c:\mbone\sdr\63920.txt" is present set home=c:\sdr on PC (GOLI) set PGPPATH in autoexec.bat or when typing it in the popup window give it as unix slash e.g c:/pgpkeyring (GOLI)

Sdr changes log


2.5.8
  - Unix version now uses Tcl/Tk from our CVS. This is Tcl/Tk 8.0.3 modified
    to remove all the path searching and include the initialisation files in
    the binary. Should solve the numerous problems with Tcl which people have
    reported (it works for rat and nte, why not sdr too?)
  - Fix font sizes in the calendar (was hardcoded pixel sizes, now measures
    the font to get the correct value).
  - Assorted fixes to authentication code
  - Many many changes to remove space leaks and memory corruption problems,
  - Add workaround for Irix bug where timezone sometimes contains an
    unmatched quote.
  - Fix SIP From URL in ACK and BYE requests.

2.5.7 Released 24 September 1998
  - Fix compilation on FreeBSD
  - Fix session creation in cases where you have a plugin but no tools for
    the media
  - Remove T/TCP code from sip_common.c (patch from Bill Fenner)

2.5.6 Released 18 September 1998
  - Many bug fixes...
  - Fixes for Irix 6.3 from Michael Kaschel (M.Kaschel@sf.hs-wismar.de)
  - Rewrite of the new session UI (wizard style interface)
  - Change order of scope zone initialisation

2.5a5 E.Whelan@cs.ucl.ac.uk 5th August 1998
  - changed version number to 2.5a5 in preparation for the release

2.5a4 G.MontasserKohsari@cs.ucl.ac.uk  31st July 1998
  - added lots of changes to implement PGP and X.509 authentication
    and encryption

2.5a4 E.Whelan@cs.ucl.ac.uk  29th July 1998

  - added code so that the media tools can be started encrypted 

2.5a4 E.Whelan@cs.ucl.ac.uk
  - modified so that a privacy header is used in the case of symmetric 
    encryption. 
  - increased version number as old version with no header will not
    interoperate.

2.5a3 mjh@isi.edu, 1998/04/21
  Fixed SIP bug when inviting to public sessions
  Fixed SIP URL syntax
  Increased version number as SIP will no longer interoperate with 2.5a2

2.5a2 c.perkins@cs.ucl.ac.uk

  mjh, 26th Mar 98
- fix address book

- fix SIP code so that when a SIP announcement arrives followed by a
  SAP announcement for the same session, the right thing happens.

- replace sd_addr with sap_addr and sd_port with sap_port to make it
  more obvious what these variables do.

2.5a1 c.perkins@cs.ucl.ac.uk

- Fix SIP for encrypting sdr 

2.5a0 

- Rename 'nt' to 'nte'

2.4a8 E.Whelan 4th Feb 98

- changed code to remove the symmetric encryption keyid

2.4a8 mjh 28th Jan 98

- changed address field in announcements to be FQDN as per new SDP spec.

- added lots of code to try hard to get the FQDN, even when the machine is
  not well configured.

- fixed longstanding bug where email and phone fields are switched in 
  announcements.

2.4a8 January 98 E. Whelan

- Added lots of code for symmetric encryption of the announcements

fenner 20th Jan 98

- I had previously sent you some code to handle duration > interval,
  e.g. "active every week for 2 weeks".  I noticed today a session that
  was "active every 2 days for 2 days", which could use the same fix.

2.4a7 mjh

- fixed calendar bug that caused daily times to be not shown for sessions
  during November and December.  Also fixed year 2000 bug in calendar code.

2.4a6 mhandley

  many changes to start to bring sdr SIP implementation in line with the
  soon-to-be-releases spec.

- fenner@parc.xerox.com:
  
- minor bug fixes
 
- fixed problem with multiple repeats only showing the first

- some restructuring to clean up record_session

- user hook added for adding debug code or user extensions via sdr.tcl.

2.4a5 mhandley

- new highlighting of sessions caused errors when the session timed
  out with the session disply window visible.  Now fixed.

2.4a4 mhandley 9 May 1997

- fixed plugin parser so new plugins for an existing tool properly override
  old ones.

- disabled middle button paste in sdr main window.

- added scrollbar to tool preferences.

- added bindings to main window icons so they behave the same as the text

2.4a3 mhandley 8 May 1997

- added code to handle SIP redirects from a sip_server

- bug in handling sip failure responses fixed.

- minor structuring to permit some common code between a sip_server and sdr.

- added code so sdr can register its user with a sip_server on startup
  using HTTP POST (Content-type: application/x-sip-loc).  This will allow
  a simple dynamic directory to be maintained, perferably one instance
  per site,  but other arrangements are also possible.

- first pass at sip_server.

- fixed some minor bugs in the keyboard-beep code that is used when
  sdr is being called.

- added a "While you were out" window that lists calls that were unanswered.

- added check on SAP version number so sdr rejects announcements with version
  greater than 1 in preparation for potential SAP changes.

- added code to trim URL strings if the won't fit in the status line of the
  web browser when you put the pointer over the a hot string instead of 
  letting tk resize the browser to fit the string.

- added a filter so you can hide Test sessions in the main sdr window.

- re-wrote the main session listing code to use a Tk text widget
  rather than a listbox to allow colours, multiple fonts and images in
  the listing.  

- Added code to display the session type as an icon in the session listing 
  and to disable this from the preferences if desired.

- Added code to display future sessions as greyed out in the session listing.

- Added code that allows the sessions to be sorted primarily on
  session type, or alphabetically depending on user preference.

- Added code to session startup to prevent sdr needing to query the
  user whether to use an old rule for a tool or a new plugin that
  overrides the old rule.

2.4a2 mhandley 29 Apr 1997

- fixed bugs in SIP code that meant a lost response to a call wasn't
  resent properly.

- fixed bug that meant quiting after initiating a SIP session caused an
  error when saving the cache.

2.4a1 mhandley 28 Apr 1997

- added code to allow a SIP alias to be used in addition to the username.

fenner@parc.xerox.com 28 Apr 1997

- string compares replace "!=" in new.tcl to avoid problems with numeric 
  ad ids.

- lappend used in place of simple string concatenation in sdr.tcl to
  avoid problems with tcl getting confused with "{" in a string.  

- make the calendar keep track of ending year; I saw a session which
  ended in 366 days (or something) so the end time on the 2nd day was
  displayed incorrectly.

- Keep a 20-page memory cache of web pages

- Add "reload" which ignores memory cache and causes proxy cache to reload too

- Use resources for font names instead of hardcoded values

- Size the window with "prefont" so it's the right width.  Unfortunately
  this sometimes makes stuff that's supposed to be normal in the prefont.

- Make multiple forms on the same page work by making the widget path
  depend on the form number

- Use T/TCP if available for web requests

- Extend knowledge of Solaris bugs in www_fns.c

- Handle reload requests


2.4a0 mhandley 28 Apr 1997

- added a simple address book for SIP calls.  Functionality will be
  expanded in due course.

- re-wrote SIP code to use SIP v2.0 rather than the old SIP v1.0:
  current status:
   only UDP implemented
   doesn't handle redirection
   doesn't handle negotiation
   absolutely minimal functionality to be able to make and receive calls

- fixed longstanding bug where saving preferences could fail if ~/.sdr
  didn't exist.

2.3a3 mhandley

- complete re-write of session listing display code to make it much
  more generic and (hopefully) more robust.

- bug fixed where encryption key variable wasn't being initialised,
  so it was possible for sdr to put sessions in the private window
  when they should have been public.  (thanks to Bill Fenner)

- modifications so that sdr accepts SAP announcements with CRLF
  separating lines rather than just LF.  Note LF is the standard, CRLF
  is acceptable but not advised.

2.3a2 mhandley

- changes made so encryption is removable for export from US.

- memory leak in send_advert fixed (thanks to Bill Fenner).

- fixes added to sd_listen.c to prevent possible core dumps when a
  session is received with missing compulsory fields.

2.3a0 8 Oct 1996 mhandley

- encryption added:
   new cache directory added
   new SAP packet format adopted
   new UI code to separate encrypted and plain text sessions
   new preferences to specify encryption groups
   new code to store encryption group keys and other config data
   QFDES code from Saleem Bhatti et al included
   many other small changes related to encryption

- bugs in calendar fixed
   repeat sessions that repeat more than 3 months were treated incorrectly

- new session interface
   can no long create sessions that repeat for time x every y seconds
   where x > y/2.

- more label changes as a result of study by Louise Clark.
  "Detailed Time" button is no more - details are shown by default.

- sdr now does also attempt to read plugins from /usr/local/etc/sdr/plugins
  and a startup file from /usr/local/etc/sdr/sdr.tcl, in addition to
  those in ~/.sdr (or ~/sdr on Windows)

2.2a23 25 Sept 1996

- bug in the order of initialisation of Xresources was causing plugins
  to be read from the wrong place.  

- Two-way call disabled in Quick Call window pending being fixed properly.

2.2a22 9 Sept 96

- dumb state initialisation bug that carried email/phone state forward
  from one session to the next fixed.

- extra bindings added to work around tk bug in listbox scrolling in the 
  sdr main window (was possible to scroll sideways even though there was a
  binding to forbid it).

- many label changed as a result of a usage study by Louise Clark, and
  extra help labels added to preferences and calendar for beginners.

- string comparisons replace "normal" comparisons in reshow_sessions
  to avoid unwanted type conversions which were causing very occasional 
  errors.

2.2a21 13 August 1996

- code added to store the PID of media tools and to produce a warning
  (on UNIX only) if the address or port is changed in a session where
  we already have media tools running.  

  This will not work (but should fail silent) on systems other than
  SunOS and Linux which have a BSD "ps" as it will default to doing "ps
  -p " unless someone adds them to the relevant switch statement in
  media_changed_warning in sdr.tcl

- editing bug fixed: sdr is now smarter about when it really needs to
  reallocate multicast addresses when you switch between TTL scope and
  Admin scope in the technical interface.

- deleted session popups are now (again) removed when you hit delete.

2.2a20 12 August 1996 mhandley@cs.ucl.ac.uk, fenner@parc.xerox.com,
                      brezak@apollo.hp.com

- admin scope editing bug on the "normal" interface fixed - default
  local scope was incorrectly getting asserted.  bug reported by
  George Michaelson.

- admin scope scope bug fixed - command bindings were slightly incorrect
  due to previously missed tk3.6/tk4 inconsistency, but had til now been
  masked by another bug.

- code added to see if we really need to re-allocate addresses when the admin
  scope is changed so that pseudo-scopes like site,region,world don't need
  to change addresses when we change between them, but really admin scopes
  do.

- minor patches to build sdr on NT 4.0b2

- repeat time handling was botched by changing starttime if it was
  earlier than today, repeat times were then calculated from right now
  as opposed to the original start.  Although I can't explain why, this
  caused sessions with repeats to show up on every single day of the
  calendar.

- if a session had multiple repeats in the same day, the second line
  would not highlight or bring up the session window

- if a session had multiple repeats in the same day, there would be
  empty space at the bottom of the calendar detail box.

- the list of bookings would not be sorted by name because it got
  sorted by aid.  removal of the sort by aid allowed it to fall back
  to the naturally sorted order of $fullix().

2.2a19 4 August 1996 mhandley@cs.ucl.ac.uk

- Old bug in determining when to allocate new addresses/ports and when
  not to because we're editing an exising session fixed yet again.

2.2a18 1 August 1996 mhandley@cs.ucl.ac.uk

- calendar TCL bug fixed - thought I got all these last year, but no...

2.2a17 30 July 96 mhandley@cs.ucl.ac.uk

- plugin mechanism extended to provide prototype support for 
  audio redundancy and for dynamic payload types.

2.2a16 3 July 96 mhandley@cs.ucl.ac.uk

- Plugin mechanism extended to allow attributes to be specified to be
  set by default for particular formats.

- Vat plugin modified to set ptime:40 attribute by default when session
  is announced.

- Code to work around pre-tk4.1 text widget line wrap bug removed from
  session creation interface (was causing session editing problems).

- Improved the SDP repeat time code:
   - improved (but still incomplete) offset handling
   - added parser for unit specification characters "d","h","m" and "s".

- Change args to ui_init to cope with changed behaviour of Tk_ParseArgv
  which now re-writes the argument list.

- SIP session creation fixed to remove spurious "0" attribute.

- Broken SIP receive code fixed - incorrect parameters were given to bind
  when CANT_MCAST_BIND was ommitted.

- Cancel button added to "Start Tool" popup.

- Calendar arrows were incorrect with multiple repeats per day and the
  last of them terminating on the next day.

- Modified cache entries to store whether or not an annoucement is 
  trusted so that spoof announcements claiming you were the originator 
  don't get re-announced but do get displayed (previous fix just 
  ignored them).

9 July 96 batie@aahz.jf.intel.com

- added extra checks to exit cleanly if we can't find our own hostname
  or address.

9 July 96 van@ee.lbl.gov

- In the process of converting sdr from using the xrand48 routines to
  'random()', I introduced a serious bug in the announcement logic.  The
  symptom is that the first two announcements are made then no more.
  The reason is that drand48 returns a double on [0..1) and random
  returns a u_int on [0..2^32) so the first randomized interval in
  timed_send_advert is huge.

- I noticed that if someone sends an announcement claiming you are the
  originator then you quit & restart sdr, you will obligingly originate
  the announcement.  I changed the receive packet handler so that it
  ignores announcements from someone else if we are the original source.

- I also added a 'sdr_delete_session_hook' to sdr.tcl (analogous to
  sdr_new_session_hook) so I could make a ~/.sdr/sdr.tcl to log when
  sessions are created & deleted (seems like an easier way to debug than
  the commented out 'puts' lines in the original).


2.2a15 3 July 96 fenner@parc.xerox.com

- Make a sip error message not look weird by not mixing printf() and
  perror() (just change it to fprintf(stderr,)

- Make announce_error() call tkerror with only one argument and
  print the actual error to stderr instead of the return from tkerror,
  and also use strncpy to not overrun statically sized buffer

- Make sdr automatically move ~/.sdr.tcl and ~/.sdr_prefs to their new
  locations, and announce that it has done so

- Get rid of an unneeded catch in sdr.tcl

-  Clicking on new media would not assign them port numbers, and
  switching back and forth between TTL and Admin scoping would produce
  ... strange results (the first time you clicked back on Admin scope,
  you would still get ttl scoped addresses)

- I also made generate_address default to 224.2.128.0/17 instead of
  224.2.0.0/16, so that the "admin scoped ttl" and the raw TTL addresses
  agreed.


2.2a14 2 July 96 fenner@parc.xerox.com

- Radically updated the web stuff to fix its history mechanism; Now
  there's one entry point to display the current point in history,
  and another entry point to add a new page to the history and make it
  current and call the other routine, so that you can't display a page
  that you don't have history for.

- Modified sd_listen.c to copy stuff into heardfrom and origsrc no
  matter what.

- Most of the other changes have to do with the new style of keeping
  the fullindex sorted.


2.2a13 5,15 June 96 mhandley
- Fixed bug in 2.2a11 preference applying after a new session arrives
  when the preferences window is up.
- Session-type attribute and user interface code added  along with icon 
  to display session type in popup window.
- Makefile and ui_init.c changed to allow separate compilation of tcl
  files for ease of development (reversing one of Van's changes).
- General session attribute handing code added.
- Intenal attribute list format changed to be newline separated to cope
  with spaces in SDP attributes.
- "tool" session attribute added to session announcements to aid debugging
  when other session directory tools become more common.
 
2.2a12 11 Jun 96 van@ee.lbl.gov

- Several ifdef's & changes to support building under Win95/WinNT.
  The Windows implementation is complete & fully functional except:
    - sip support is disabled
    - the conference bus is disabled (it would be a nop under windows
      anyway)

- Moved all config files into ~/.sdr (~/sdr under Windows) directory.
  Name of this directory can now be set with Sdr.sdrHome X resource.
  Changed filenames are:
    ~/.sdr_prefs   ->  ~/.sdr/prefs
    ~/.sdr.tcl     ->  ~/.sdr/sdr.tcl
    ~/.sdr.<lang>  ->  ~/.sdr/<lang>

- under windows, use the right button (which tk calls `button 3') for
  the 'immediate start' funtion since there is no button 2.

- replaced rand48 calls with random calls, using the random.c from
  the vic/vat distribution.  This is faster, more portable & more
  random than rand48.

- converted to release version tcl7.5/tk4.1.  Set up makefiles to
  generate lib.tcl from installed tcl/tk library files rather than
  using handbuilt lib.tcl that might be from incompatible tcl version.

- since winsock i/o works via callbacks rather than 'select', replaced
  calls to Tcl_CreateFileHandler() with calls to linksocket() (in new
  module iohander.c).  linksocket will take care of getting the winsock
  callbacks under win95/nt & will call Tcl_CreateFileHandler under unix.

- since you can get socket callbacks at any time (e.g., while other
  tcl code is being executed), most Tcl_Eval() calls needed to be
  Tcl_GlobalEval() calls to make sure they executed in the correct
  context.

- since winsock callbacks can arrive as soon as the handler is declared,
  need to create enough of the GUI to deal with callbacks *before*
  linking sockets otherwise we'll randomly crash during startup.

- tried to use new tcl7.5 clock facilities rather than localtime/strftime
  since the latter may not work on all systems that run tcl/tk
  (e.g., the Mac).  Changed C routine gettime to tcl routines gettime
  and gettimenow.  Changed '%e' in time format with %d since Microsoft
  (and Posix) don't support %e.

- got rid of 'please wait' popups when running under Windows (popup
  windows are *way* to expensive to use under Win95).

- changed the www receive code to use recv() rather than fdopen on
  the socket fd.  sockets aren't files under windows so this won't
  work and, anyway, recv is simpler and faster.

- the directory traversal code used for cache loading was very unix
  specific.  replaced it with a tcl procedure that uses tcl file
  globbing to get cache file names then calls a new C routing
  load_cache_entry() to validate & load one cache file.

- replace bcopy/bzero calls with memcpy/memset calls since former isn't
  portable to windows or most posix systems.

- added error announcement dialog box with optional traceback to the
  startup processing (otherwise you can't tell what went wrong under
  windows).

- made the internal help file generation use the same tcl2c scheme
  as the internal tcl file generation (since any compiler that can't
  handle one can't handle the other, e.g., Microsoft's VC4.x).

- made the output-characters-instead-of-strings mode of tcl2c be a -c
  flag rather than a compile time option.

- tried to simplify the makefiles by using suffix rules for the html
  to c & tcl to c conversions and by using VPATH to locate the files.
  (this required a bit of renaming to rationalize the html vs. ehtml
  names and file vs. array tcl names.)

- Bug fixes:
   - rearranged several error msg printers that did "fprintf" followed
     by 'perror' (the fprintf will wipe out errno).
   - got rid of some debugging 'puts' statements in start_media_tool.
   - fixed a few of the many gcc -Wall errors (ones that looked like
     they'd cause problems under windows or other architectures).
   - replace a very creative way of trying to turn a string into an
     ip address with a more mundane version that works.
   - rearranged the socket/bind/connect/setsockopt calls to follow the
     one and only sequence that windows will accept.
   - ran all the tcl code through tclCheck & tcl_cruncher to check
     brace, paren, quote, etc., matching.  This found a few errors
     that would have bitten someone under the right circumstances.
     (doing this required nuking some commented out, obsolete or debug
     code that fooled the checker).
   - fixed bug in tcl2c when CANDOBIGSTRINGS isn't defined -- wasn't
     adding null byte string terminator.
   - got rid of pointless bind to 0.0 in www recv code (it does nothing
     and microsoft gives an error when you do it).
   - made quit button do a 'write_cache' since doing it only when main
     window is destroyed can cause cache to not get written out.

2.2a11 31 May 96 fenner@parc.xerox.com

- Change iconbutton to raise the button before invoking command like the
  normal tk button, so that if you click on "more info" and then dismiss
  the window you don't get an error when the web page finishes
  loading.
- Delete the B2-Motion event to prevent accidental scrolling of the session
  windows.
- Attempt (it doesn't work for unknown reason) to bind j and k to scrolling
  up and down in the session windows like in sd.
- Make the session redisplay sort case-insensitive
- Attempt to add popups for more buttons in the "new" interface
  (but the popups need to learn about iconbuttons)
- Make web status "Parsing" while parsing the page, and "Finished" only
  after done parsing
- Make "Invalid Content Type" message reflect the actual content type
  instead of the data of the last header that was parsed
- Implement "#xxx" anchors (use catch instead of foreach?)
- Indent <dd> and center <center> (sometimes)
- Partially implement <META HTTP-EQUIV> for "poor man's redirect"
- Parse </br> as <br> since Netscape allows it
- Allow comments with <!--stuff , the old code required a space
- Add "parsestr" function to parse out KEY=value or KEY="va l u e" pairs
- Impement full RFC1866 list of character elements, including &#nnn;
- Implement non-blocking connect for webto, keyed on #define NBCONNECT
  so it can be conditionalized per platform
- Use ~/.RTPdefaults if it exists to guess name and email
- Fix bug in tech_new's decision about configuring name and email
 
- Fix "Illegal Scope Value, Scope value must be between 0 and 255" error
  if you don't click on any scope-related buttons and just create a session.
- New preferences scheme.  Each panel of the preferences menu
  has its own function, named "pref_XXX", which takes several
  possible arguments:
        copyin          copy from sdr's variables to prefs(XXX_variable)
        copyout         copy from prefs(XXX_variable) to sdr's variables
        defaults        set the prefs(XXX_variable) to default values
        create window width height
                        create the user interface using window as your
                        top level & make sure your widget matches the
                        width and height
        save file       output tcl commands to file to set the sdr
                        variables to their current values, e.g.
                        puts $file [list set webproxy $webproxy]
 
  One thing to potentially add is "verify", e.g. make sure all values
  are within their allowed range (like no empty phone numbers allowed)
- Added listening to the sd address, conditionalized on
  LISTEN_FOR_SD
- Fix typo; the ttl for the admin scope "site" is actually 15.
- Set ldata($aid,medianum) to 0 for sessions with no media.
  This was previously done in another section of the function
  but needs to be done in all cases.
- Add sdr_new_session_hook, which gets called whenever a new session
  is heard.  It may be in the wrong place.
- Fix confusion about exiting; if the ~/.sdr directory didn't exist then
  the cache directory wouldn't get created so the cache wouldn't get written.
- Fix UI weirdness in preferred session selection.  Two things:
  - The two listboxes could potentially scroll independently of each other.
  - Clicking on an entry near the bottom of the list can shorten the list,
    causing the listbox to scroll.  Fixed by adding the new value before
    deleting the old one.
- Change \r\n to \n only, and then change \r to \n to attempt to handle
  HTTP servers that return \r-seperated lines.  Also fixes the \r's
  at the end of <PRE> lines.
- Made anchors use "catch" instead of "foreach" to move to the mark
- Media setup bug in quick-call fixed.

2.2a10 16 May 96 mhandley
        Problem with backgrounded sdr writing startup messages fixed.
	Session display windows now disappear when the session times out.
	Xresources now work again (haven't been since the port to Tk4.0)
	pcm2/dvi2 now the default packetisation if a ptime attr is not
          specified (suggested by Van Jacobson)
	Bug preventing setting of midnight start times fixed.
	Bug preventing sdr starting sessions with several streams of the 
          same media fixed.
	Experimental code added to allow sdr to continue running after logout 
          and X display destruction ("-s" flag" specifies this)
2.2a9 9-12 May 96 mhandley
        Preferences user interface completely re-written to reduce
          complexity and number of windows required.
        Mechanism to specify preferered tools for each format added.
        UI Bug in specifying prefered sessions fixed.
        Can now copy from session information window into X cut buffer
          for phone numbers, addresses, etc.
        Cache files now get written on logout (failed X connection) as
          well as on hitting "quit" or announcing new sessions.
        A first attempt at sorting out keyboard (Tab) traversal of
          the user interface (as in Motif Compliance!)

	WWW browser patches from Bill Fenner:
	- The "display url" code tended to make the status "Finished" 
	  when it shouldn't be, so I started using a global variable to 
	  hold the status.
	- Parse and use "<BASE HREF=>" elements; our proxy server depends 
	  on this (e.g. if you ask our proxy server for 
	  ftp://ftp.parc.xerox.com/pub/net-research it puts in  
	  <BASE HREF="ftp://ftp.parc.xerox.com/pub/net-research/"> instead 
	  of sending a  redirect.

2.2a8 8 May 96 mhandley
        command line option "-d1" added to aid debugging of announcement
          problems.
        initialisation bug with ttl scoped sessions when new admin scope
          zones were defined is now fixed.
        initialisation bug in setting ttl for admin scoped sessions fixed.
        scrollbar now works again when specifying visible sessions in prefs.
2.2a7 4-6 May 96 mhandley
        Some parser checks that were missing added.
          - should prevent crashes with broken MCM sd announcements.
        Calendar interface redesigned to use pop-up fewer windows.
        Calendar now handles repeat times properly.
        Incoming invitations now force the popup of the invitation window
          on window managers like twm which nornally delay window placement.
        Minor changes to prevent sdr exiting in certain error conditions.
        long phone numbers bug fixed.
2.2a6 27 Apr 96 mhandley
        TkPlatformInit redefined to fix tk4.1b3 stupidity trying to
          explicitly load $TK_LIBRARY/tk.tcl
2.2a5 15-26 Apr 96 mhandley
        Basic SIP implementation added.
          allows users to invite other users to join advertised sessons
        Tcl SDP parsers added for SIP messages.
        Sensible error message now produced when DISPLAY is incorrect.
        better support for monochrome displays added
        plugin parser made more robust to odd spaces
        new session window made shorter and fatter
        moved cache files from .sdr dir to .sdr/cache dir.
        youremail variable added to plugin mechanism
        bug in plugin attr parser fixed (was preventing wb session launch)
        check added so sdr ignores announcements with later versions than 0
        repeat times now displayed properly in session display window
        window placement code improved - windows should get moved less
        added code to parse mailto URLs (but not to handle them yet)
        bug displaying sessions with no media fixed.
        bugs in recording startup fixed by Bill Fenner
2.2a4 15 Apr 96 mhandley
        macro/value pairs added to plugin mechanism
        vat protocol id's added back to vat startup script
        TCL bug in SunOS4 startup config worked around
2.2a3 15 Apr 96 mhandley
        stupid bugs in a2 fixed
2.2a2 12-13 Apr 96 mhandley
        plugin attributes now finished
        first pass at built-in "plugin" config files
        plugin help pages completed
        many little changes to WWW browser to improve appearance of help pages
        moved all platforms to tk4.1/tcl7.5
        some low-priority status messages now appear on sdr main 
          window rather than annoying little popups.
2.2a1 9-10 Apr 96 mhandley
        times with leading zeros bug fixed.
        really fixed(!): double clicking in main window produced a tcl error
        unknown media types now handled gracefully.
        bugs introduced with spec changes fixed.
        startup code for tools moved to separate modules and
          re-written to use plug-in config files to make configuration
            much more flexible and simpler.
          .sdr.tcl no longer used to configure session startup
        plugins used to configure menus when creating and editing sessions
        plugins used for fmt/proto name mapping in session listings
        response improved whilst writing cache file
        rtp mapping code from 2.2a0 removed
2.2a0 3 Apr 96 mhandley (telnet from California)
        Octal problem with changing date fixed but not tested.
        protocol fixes to support current SDP spec added.
2.1a12 30 Jan 96 mhandley
        fixed: double clicking in main window produced a tcl error
        ptime attribute added for audio and code to start up {pcm,dvi}{2,4}
        added.
        tearoffs removed from pull-right media attribute menus
2.1a11 26 Jan 96 mhandley
        Fixed bug in storing addresses for address allocation

       25 Jan 96 fenner@parc.xerox.com
        FreeBSD port done.
        strerror() added to compat.c
        Union in a struct in_addr replaced with bit manipulation for
        4.4 BSD compatibility
        Added the ability to use a proxy server and a preference to go
        with it, and made the WWW browser error messages slightly nicer.
        Added (not-quite-fully-compliant-but-99%) HTML comment parsing, and
        got rid of an infinite loop that occurred on pages with bare &'s (see
        http://town.hall.org/).

       24 Jan 96 mhandley
        Lots of restructuring as a result of work on the sdr_server.

2.1a10 13 Jan 96 mhandley
        Simple interface added for session creation by less techincal users
        Simple interface added for session display
        Stupid timing hole resulting in session duplication while
        editing sessions now fixed.
        Default audio protocol changed to be RTP rather than VAT protocol
        Lots of restructuring in code to create new sessions.
        A little restructuring in session display code - now more robust to
        sessions being modified.
        .sdr_cache is now obsolete, and is replaced by the .sdr directory
          - this makes storing encrypted sessions cleaner
          - this also prevents incorrect editing of one session's cache entry
            corrupting others
        old .sdr_cache files get read (once) and then deleted.
        Calendar daily entries are now hot (popup the relevant session).
        Calendar daily entries now only get an arrowhead if they start or 
        finish on that day.
        Hot entries now get highlighted on entry (in all windows).
        Clicking on an already raised session in sdr main window now dismisses
        it - this makes it easier to browse sessions.
        WWW browser and help system now handle HTML escaped special chars
        WWW browser bug displaying HTML after last tag fixed
        WWW browser handing of Relative URLs from redirected pages now fixed.
2.1a9 9 Jan 96 mhandley
        Session Timeout timer-handler moved to start of session timeout code
        to improve robustness
        TCL session state time values were not all correctly set up for
        infinitely long sessions - now fixed.
        Session deletion code made more robust.
        Spurious error message with length 0 sdr_cache file fixed.
2.1a8 6 Dec 95 mhandley
        Stupid bug dealing with ad id comparisons fixed        
2.1a7 2 Dec 95 mhandley
        middle-button on empty session window error fixed.
        incorrect port bug when starting nv fixed
        some spurious debugging messages disabled
        tearoffs removed from menus (shouldn't have been there in the first
        place)
2.1a6 1 Dec 95 mhandley
        tk4.0 porting bug related to editing repeated sessions fixed
        spurious incorrect error messages removed.
        ballon help initial state was inconsistent with UI - now fixed.
        text-wrap problem is session popups fixed.
        calendar bug with times before 1am fixed
        editing sessions didn't clear previous text media - now fixed.
        tk4.0 porting bug in WWW browser image link code fixed.
        browser history list is now cleared on dismissing the window
         - thanks to Bill Fenner for reporting all these!
        BUGS and CHANGES now included in help pages.
2.1a5 30 Nov 95 mhandley
        Released sdr with sd compat timestamps rather than NTP timestamps
         - now fixed!
        sscanf problem in parser on HPUX fixed - thanks to Piers O'Hanlon
        session-id and session-versions fields were swapped - now fixed
        spurious error message when parsing indefinite sessions removed
2.1a4 28 Nov 95 mhandley
        TK_LIBRARY dependency had found its was back in with tk4.0 
        - removed again
        Paste to description box tk4.0 bug fixed
        Editing of ttl scoped sessions reset ttl - now fixed
        Stupid calendar month wrapping bug fixed
2.1a3 27 Nov 95 mhandley
        small changes related to porting to other platforms
2.1a2 25 Nov 95 mhandley
        Vat and vic default program names fixed
        Media labels in "new" window fixed
        Sdr.tcl split in two and cleaned up slightly
        Error checking improved in config files
        "new" window disabled "protocol" and "fmt" menus fixed
        setmediamode re-written
        UK scope shouldn't have been in as a default!
        Help pages greatly extended
        "Bugs" and "Changes" now automatically included in help system
        Debugging turned off by default
2.1a1 24 Nov 95 mhandley
        Ported to Tk4.0 - loads of stuff changed
        Protocol updated to draft-ietf-mmusic-sdp-01 subset
        IconButton re-written to work with tk4.0
        Horrible workaround added to prevent clash between iconbutton functions
          and widgets with same names (used to work in tk3.6)
        BalloonHelp modified to work with tk4.0
        Some new balloons added - more are needed
        WWW browser modified to work with tk4.0
        More preferences options added + preferences re-written somewhat
        Colour changed
        Vat and vic startup scripts totally re-written - now supports
         conf control channel for voice switching
        Tool to start for nv, ivs, and rtp audio now a preference selection.
        Allocates even ports for rtp
        Allocates prividged ports according to mrouted 3.6 rate limiter
        "new" protocol menu fixed
        Loads and loads of little things to do with tk4.0
2.0a10 17 Aug 95 mhandley
        stupid tcl bug with dates with leading zeros fixed
2.0a9 13 Jul 95 mhandley
        administrative scoping now works on multiple addresses/ports
2.0a8 12 Jul 95 mhandley
        administrative scoping added to interface - currently hardwired scopes
        but address dependant on scope working
2.0a7 12 Jul 95 mhandley
        nt added start_whiteboard procedure
        multiple multicast addresses were broken in parser by additional 
        strlen check in a4 - now fixed
2.0a6 11 Jul 95 mhandley
        Bugs fixed:
        Now handles main window being slightly offscreen (-ve geometries)
        Dhild windows now get moved completely onscreen (I hate TK sometimes!)
        Bug in session deletion fixed - sessions weren't getting deleted 
        permanently.
        Bug in www browser fixed - now handles any sized file
        Session deletion/selection with empty main window now doesnt
        cause an error
2.0a5 10 Jul 95 mhandley
        Corrected non-conformance with SDPv2 draft-01
        Transport protocol field added to "m=" fields
         - not compatible with previous versions!
2.0a4 4 Jul 95 mhandley
        First released version conforming to SDPv2 draft-01
2.0a3 20 Jun 95 mhandley
        too many changes to list!
        Handles most SDPv2 times and repeat times
        Handles SDPv2 fmt fields
2.0a2 19 May 95 mhandley
        built in WWW browser added to sdr
1.2a11 10 Mar 95 mhandley
        Recording functionality added
        Bug in day calendar popup fixed
1.2a10 2 Mar 95 mhandley
        Language internationalisation completed.  Now reads ~/.sdr.${LANG}
        file for internationalisation code.
1.2a9  1 Mar 95, mhandley
        Fixed bug in calendar - times before 10am didn't work!
        Language internationalisation partially added.
1.2a8, 28 Feb 95, mhandley
        Calendar label problem with German language labels fixed.
        Calendar day numbering problem with month 2 and month 3 fixed
        "unknown command .desc?.f.f0.desc" error fixed.
The sdr Session Directory:

The sdr Session Directory:

An Mbone Conference Scheduling and Booking System

Mark Handley
Department of Computer Science
University College London
Draft 1.1, 14th April 1996

Sdr is a Session Directory designed for announcing and scheduling multimedia conferences on the Mbone - the multicast backbone of the Internet. Sdr is loosely modelled on sd - LBL's Mbone Session Directory. Sdr extends the sd model in a number of ways, particularly in the degree of detail about the timing and resources required by a conference, and in the provision of a much more flexible interface for querying the existence of sessions or of any sessions that may potentially clash with a new session.


The Session Announcement Model

The Session Announcement Model

Sdr uses an announcement protocol called the Session Directory Announcement Protocol. In its simplest form, this involved periodically multicasting a session announcement packet describing a particular session. To receive SDAP, a receiver simply listens on a well known multicast address and port. Sessions are described using the Session Description Protocol (described below). If a receiver receives a session announcement packet it simply decodes the SDP message, and then can display the session information for the user. The interval between repeats of the same session description message depends on the number of sessions being announced (each sender at a particular scope can hear the other senders in the same scope) such that the bandwidth being used for session announcements of a particular scope is kept approximately constant.

If a receiver has been listening for a set time, and fails to hear a session announcement, then the receiver can conclude that the session has been deleted and no longer exists. The set period is based on the receivers estimate of how often the sender should be sending, and is (arbitrarily) set to ten times the estimated send period. It is possible for network partitions to force inadvertent deletion of sessions, but inadvertent deletion due to packet loss is extremely unlikely. In any event, such a deleted session will be reinstated as soon as the network partition is resolved and another announcement packet is received.

To allow relatively quick startup and display of long-lived sessions, sdr keeps a local (per user) cache of sessions. Upon startup, sdr reads this cache, and displays those which have not yet reached their expiry time. This cache also holds sessions created by its owner, and upon sdr startup, these sessions start to be re-announced. Note that with this simple model, a user must have a copy of sdr running for a session created by that user to be announced and to not time-out at receivers.

Extensions to SDAP not currently implemented involve allowing other local copies of sdr to make proxy announcements of a session when its originator is not announcing it. Also other copies of sdr can serve as cache servers, so that upon startup, a copy of sdr queries any other locally running copies of sdr to update the entries in its local cache. This can be extended by having an sdr daemon running continuously at a site and performing both the proxy announcement and proxy receiver tasks - however the daemon is not essential for sdr to be used - it simply provides an improvement is performance.

The Session Description Protocol

The Session Description Protocol

The Session Description Protocol (SDP) is an ASCII text based protocol for describing multimedia sessions and their related scheduling information. It was originally based on the protocol used by the sd session directory from Lawrence Berkeley Labs, but has been extended and generalised significantly since then.

The purpose of SDP is to convey information about media streams in multimedia sessions to allow the recipients of a session description to participate in the session. SDP is primarily intended for use in a internetwork, although it is sufficiently general that it can describe conferences in other network environments.

A multimedia session, for these purposes, is defined as a set of media streams that exist for a duration of time. Media streams can be many-to-many. The times during which the session is active need not be continuous.

Multicast based sessions on the internet differ from many other forms of conferencing in that anyone receiving the traffic can join the session (unless the session traffic is encrypted). In such an environment, SDP serves two primary purposes - as a means to communicate the existence and timing of a session, and as a means to convey sufficient information to enable joining and participating in the session. In a unicast environment, only the latter purpose is likely to be relevant.

Thus the information SDP must convey includes:

  • Name and purpose of session
  • Time(s) the session is active
  • The media comprising the session
  • Information to receive those media

Scheduling Sessions

Scheduling Sessions

New sessions can be created by pressing the ``New" button on the sdr main window. Every session must have a name, a short description, a scope, contact information, a start time and a stop time. In addition, sessions may optionally also possess links to further information in the world wide web, a number of detailed media descriptions, and more detailed timing information.


Links to the World Wide Web

Links to the World Wide Web

A session announcement can contain an Uniform Resource Locator (URL) as a link to related information in the world wide web. The preferences menu determines how sdr follows such references - three options are supported:

  • Using the simple built in WWW browser
  • Starting an external browser such as netscape or Mosaic
  • Directing an already running external browser to the URL (Mosaic and netscape permit this sort of remote control operation).
If you have an colour display of depth 8 bits, using the built in browser is recommended as external browsers use a significant number of the 256 available colours, leaving you with few colours remaining for any tools you wish to use in a multimedia conference. If you have a 24bit display, external browsers are likely to provide you with better performance and prettier displays than the built-in browser. When creating a session, it is recommended that the URL be tested (using the Test button) as typing mistakes here will make the URL useless. Media Descriptions

Media Descriptions

Media descriptions are the main reason for describing a session, as they allow the receiver of an announcement to start the correct media tools directly from sdr with all the correct flags and settings to join the conference. Sdr allows you to create conferences with up to one media tool of each of the following types:

  • audio
  • video
  • whiteboard (including shared editors)
  • text
In fact sdr can receive and start sessions with more than one of each media, but the standard interface does not permit the creation of such sessions in an effort to make the session creation interface simpler to use. To include a media in your session, select the media by clicking on the left ``X" button When a media is selected, a default media format will be selected, along with default addresses, transport protocol and ports. The media format and transport protocol can be changed using the relevant pull down menus. The address and port are allocated in such a way that they should avoid clashes with other scheduled sessions - the addresses sdr provides should normally be used, although user specified ones can be substituted if required. In particular, ports are chosen such that rate-limiting in Mbone routers will preferentially forward audio rather than video when a multicast tunnel is congested. If everyone you expect to participate in your session is likely to wish to receive all the media you have selected, then using one multicast address for all your media is appropriate. If some receivers are likely to not wish to receive some media - for example some sites have insufficient bandwidth to receive video - then selecting one multicast address per media is appropriate as this permits unwanted traffic to be pruned back from these low bandwidth participant sites. Detailed Timing

Detailed Timing

If your session is not going to be active continuously between its start and stop times, then this detailed timing information should be provided so that users that wish to participate know the precise times, and users that do not wish to participate can know when to expect your traffic to be active.

Sdr allows you to specify up to three active times or repeat intervals for your session - each active time or repeat interval specifies an addition set of times when the session will be active. The limit of three is not imposed by the protocol - if sdr receives an announcement with more than three repeat times it can decode and display it - but rather to simplify the user interface for session creation. Administrative and TTL Scope

Administrative and TTL Scope

The multicast backbone provides two methods by which the sites able to receive traffic can be constrained - TTL scope and administrative scope.


TTL Scope

TTL Scope

TTL Scope is constrained by the ``Time To Live" (TTL) field in the IP packets a multicast application sends. An application sends its data with a fixed TTL. Each multicast router that the data traverses decreases the TTL on the packets by one. Each multicast router also has a threshold associated with each multicast capable interface or multicast tunnel. If the TTL on the data packets arriving at a router is lower that the threshold of the interface or tunnel, then the packet is not forwarded out of that interface.

The multicast tunnels comprising the Mbone are configured so that it is possible to constrain a conference to a particular region of the Mbone by careful setting of the TTL. Thus the multicast tunnels in Europe are generally configured with the following thresholds:

  • Low Speed Tunnels: 128
  • Intercontinental: 64
  • International (within Europe): 48
  • Between institutions: 16-32 depending on the links involved
  • Within an institution: 1-16
Thus if I'm sending from the UK, and want my traffic to reach Europe only, I would send with a TTL of 63, which would traverse the international tunnels but not the intercontinental ones. Administrative Scope

Administrative Scope

Administrative Scope uses different ranges of multicast addresses to constrain multicast traffic to a particular region. To configure an administrative scope zone, all the multicast routers bordering that zone must be configured to be a boundary to that zone for a range of multicast addresses. Unlike TTL scope, if a conference is on a scoped multicast address, traffic sources outside the scope zone will not be able to inject traffic into the conference as administrative scope zone boundaries are bi-directional. A particular scope zone has a range of multicast addresses, a default TTL, and a name. Users of administrative scope zones only need to know the zone name (e.g. ``United Kingdom'') to be able to scope their conference correctly - the TTL and the address are allocated by sdr.

Currently there is no automatic way for sdr to learn about the relevant scope zones - this must be configured on a per-site basis. Bandwidth Allocation

Bandwidth Allocation

Each scope range (whether TTL scoped or administratively scoped) has a recommended maximum bandwidth associated with it. This is the maximum bandwidth a session should use at that scope. Most of the Mbone is currently configured for only a small number of concurrent sessions, (although this is likely to change as the Mbone is increasingly provided using native multicast in routers rather than an overlay of multicast tunnels). For this reason it is important to be able to see if a session I wish to schedule will clash with other sessions already scheduled, and to automatically set the maximum bandwidth of the tools to comprise my session.

Unfortunately many users do not know sufficient about the network to be able to decide on appropriate bandwidth figures for their session. To get around this, sdr allows users to specify their sessions as ``meetings'' or as ``broadcasts'', and lets the audio and video rates be set as ``low'', ``normal'' and ``other'', where ``other'' requires that a bandwidth value be inserted. ``meetings'' also allow the user to specify ``number of simultaneous video streams''. Sdr users this information to set fields indicating the total bandwidth of the conference and the bandwidth to be used by each tool in the conference.

If a user attempts to schedule a session that will exceed the recommended available bandwidth for that scope (based on what other sessions are scheduled) then it will issue a warning and indicate which other session the new session will clash with. Secure Announcements

Secure Announcements

Although the purpose of Sdr is to advertise sessions, not all sessions should be advertised publicly. However, it is important that even secret sessions use the same announcement mechanism, so that their bandwidth usage can be taken into account, and so that their multicast addresses are not inadvertently re-used. Thus Sdr permits secure sessions to be advertised, by announcing them twice - once unencrypted with just the bandwidth, contact info and multicast addresses, and once encrypted with all of the information including encryption keys for the media tools. Secure sessions do not appear in Sdr's listing of sessions unless the correct encryption key has been inserted.

Overview of Security in SDR

Sdr allows a session to be created as ``public'' or ``private''. To create a private session, sdr must have been pre-configured with a set of private keys. Normally these will have been exchanged via secure email. From SDR v2.5a5 there is a choice of either symmetric encryption (currently DES) or asymmetric encryption when announcing a conference. In the asymmetric case either PGP (Pretty Good Privacy) (tm) or SECUDE (tm), which uses X.509v3 Certificates and PKCS#7 style formats, can be used. The tools can be started either encrypted using DES or unencrypted. It is explicitly allowed for the media encryption keys to be sent in an unsecured announcement but, as this clearly weakens security, it is recommended that a secure announcement be used when the tools are to be encrypted.

Using X.509 Authentication and Encryption

If one wishes to use X.509 encryption and authentication one must set the environment variable X509STATE in your environment. If this is not set then the default is to only use PGP for the asymmetric encryption/authentication.

Encrypting the Media Streams

If one wishes to encrypt the media streams then, when creating a session, simply click the encryption button for the relevant media stream. A random key is generated but this can be set to a key of your choice by overtyping in the field. Overtyping is only possible if you have chosen "Technical Interface" in the Preferences menu.

Sending Authenticated Announcements

If one wishes to send an authenticated announcement then select either PGP or X.509 from the Authentication pull-down menu. A list of the private keys in the relevant keyring will then appear and you should select the one you wish to use to sign the announcement. You may be prompted for a password to access the key. You may also select "PGP+CERT" or "X.509+CERT" and the behaviour is the same as in the PGP and X.509 case before except that the full certificate is now also sent in the announcement.

Sending Encrypted Announcements

If one wishes to encrypt the announcement one should select DES, PGP or X.509 from the pull down encryption menu. A list of available keys will appear and you should select the one which you wish to encrypt the announcement with. Only other users who have either the same key for DES or the corresponding half of the key pair for PGP and X.509 will be able to decrypt and so see the announcement.

Receiving Encrypted and/or Authenticated Announcements

When one receives an encrypted or authenticated session this is indicated by the icon being reverse video. In addition there is an indication after the session name in the main Sdr window which indicates what kind of authentication and encryption has been used. When one opens up the details of the session clicking on the "Encryption Info" box will display details of the encryption used and similarly clicking on the "Authentication Info" box will bring up details of the authentication used. In order to be able to decrypt the announcement you may be prompted for a passphrase to unlock the relevant secret key.

Adding Keys To Your Keyrings

Adding keys to your PGP and X.509 keyrings must be done from outside Sdr. One should, however, add keys to your symmetric keyring from within the Preferences/Security menu inside Sdr. Receiving Announcements

Receiving Announcements

When announcements are received, they are displayed in Sdr's main window. Sdr has four modes which decide which of the currently advertised sessions are shown:

  • All Session - all the sessions received are displayed.
  • Prefered Sessions - display all the sessions except those the user has stated they're not interested in.
  • Current Sessions - display only those sessions that are currently active (including those that are permanently active)
  • Future Sessions - display only those sessions that are not currently active.

The default is Prefered Sessions, and the other options can be selected from the Preferences window. In this mode, clicking the right mouse button on a session will hide the session. A menu is available from the Preferences menu which allows the user to see all session, prefered or not, and select which are to be shown and which are to be hidden.

Clicking the left mouse button on the name of a session in the Sdr main window will pop-up a window describing the session - an example is shown in figures 3 and 4. This lists a description of the session, when it is active, contact information for the creator of the session, and the media the session comprises. Clicking on ``Start All" will start all of the media tools necessary to join the session. The media tools can also be started individually - this can be useful for restarting a tool that has failed, or for starting some tools on one machine and some on another as is common in a conference room scenario.

If the session was created by this user, then ``edit" and ``delete" options are also available. A ``record" option is also available, which will operate an interface to one of several session recording tools. This recording interface is not yet implemented. The Calendar

The Calendar

Sdr provides a second way to view sessions in addition to their display in the main window - selecting Calendar from the Sdr main window pops up a calendar view of the current month and the next two months (see figure 6). Days on which there are sessions scheduled are highlighted in blue. Clicking on a day on which there is a session scheduled expands that day to show which sessions are planned and what times they will be active (see figure 7). This allows potential future clashes to be spotted and negotiation entered into about suitable use of available bandwidth. The Web Browser

The Web Browser

Sdr has a simple built-in World Wide Web browser. This is not intended to be a full functioned browser because its main purpose is to allow references to information about sessions to be checked and browsed without starting up a fully functioned WWW browser which would use a significant proportion of the available colour table entries on most machines with 8 bit displays. Thus Sdr's built in browser does not display inline or background images - it merely displays the formatted HTML text of a page with the hyperlinks to other pages highlighted in blue. Clicking on a blue link will take you to that page. Clicking on backward will take you back to the previous page, and clicking on ``forward'' wil take you forward to the page you just came backwards from. A URL can be typed directly into the entry box at the bottom of the window if required, and the browser will then go directly to that page. The World Wide Web is really beyond the scope of this note - for more details see [2]. References


References

1
M. Handley, V. Jacobson, ``SDP: Session Description Protocol'' INTERNET DRAFT, Nov 1995.
2
M. Handley, J. Crowcroft, ``The World Wide Web: Beneath the Surf'' UCL Press, London, 1995, ISBN 1-85728-435-6.

Sdr Plug-In Modules

Sdr Plug-In Modules

Sdr can be configured to support new tools by means of plug-in modules which define the media, protocol and formats supported by a tool, along with long-form names for these formats and the flags that are needed to start up the tool.

Sdr will read files in "/usr/local/etc/sdr/plugins" and "~/.sdr/plugins" and will search for files whose name begins "sdr2.plugin.". The naming convention for plugins is "sdr2.plugin.sequence.media.protocol.format.tool" where for convenience, format is often wildcarded when the plugin file contains many formats.

New media can also defined in this manner but this should not be done without prior discussion on the mailing list "remconf@es.net" to avoid undesirable proliferation of media definitions for what really should be protocols or formats.

Sdr has built in definitions for the following:

  • audio rtp pcm vat
  • audio rtp dvi vat
  • audio rtp gsm vat
  • audio rtp lpc vat
  • audio vat pcm vat
  • audio vat dvi vat
  • audio vat gsm vat
  • audio vat lpc vat
  • audio rtp pcm rat
  • audio rtp dvi rat
  • audio rtp gsm rat
  • audio rtp lpc rat
  • video rtp h261 vic
  • video rtp nv vic
  • video rtp jpeg vic
  • video rtp cellB vic
  • video rtp nv nv
  • whiteboard udp wb wb
  • text udp nt nt
If you wish to add new protocols,formats or tools you'll need to create an appropriate sdr plugin and distribute it to anyone you wish to participate in your session.

Further information

For further information on plugins, see: Writing sdr plugins

Writing sdr plugins

Sdr plug-in configuration files follow a strict format of grouped attribute:value pairs with one attribute value pair per line. Leading whitespace is ignored. Whitespace in the value part of an attribute:value pair is significant.

Compulsory fields

For a format or tool definition file, the following attributes are compulsory and should be in the following order:
  media:media
  proto:protocol
  tool:tool-name
See the SDP specification for definitions of media and protocol. Tool-name is the name of the tool you wish to be started to send/receive this session.

Optional header fields

protoname

As the protocol will often not be very meaning full to humans, these may be followed by further definition:
  protoname:human readable versions of protocol
Protoname is used at configure menus and labels on the user interface.

create

Most plugins define media and formats that you wish to be able to announce. However, some may be just for backwards compatibility so you can receive them but do not wish to announce them. If this is the case, you can use the create field to specify that you don't wish this plugin to contribute to the session creation menus and options:
  create:no

Format definitions

After these definitions should come one or more format definitions. The minimal form of a format definition is:
  fmt:format
See the SDP specification for a more complete definition of what is meant by a format.

More normally however a format definition will require additional configuration, and this can be done as follows:

  fmt:format
  {
      fmtname:human readable version of format
      flags:command line flags for tool with this format
  }

Media Attributes

Both media and session definitions can contain optional attributes. These can be configured in the plugin on a per-tool or a per-format basis.

Attributes can be of two types - either with a set of values, or just on/off.

On-off attributes can be configured as follows:

  attr:attribute name
  {
      attrname:human readable version of attribute
      flags:command line flags for tool with this attribute
  }
Attributes with a set of values can be configured as follows:
  attr:attribute name
  {
      attrname:human readable version of attribute
      attrvalue:one possible value of attribute
      {
         attrvaluename:human readable version of this attribute vale
         flags:command line flags for tool with this attribute and value
      }
      attrvalue:another possible value of attribute
      {
         attrvaluename:human readable version of this attribute vale
         flags:command line flags for tool with this attribute and value
      }
  }
Either type of attribute may be used within a format definition (if the attribute is format specific) or after all the format definitions are complete (if the attribute is independant of the format).

This mechanism assumes you can explicitly list all the values of an attribute. Whilst this is often the case, it is not always so, and sdr plugins also allow the use of the macro and value definitions to allow flexible passing of attribute values directly to the media tool. See below for more details.

noattr

Occasionally you want to specify a behaviour to apply when an attribute is not present. To do this you use the noattr definition as follows:
  noattr:attribute name
  {
      flags:command line flags for tool if this attribute is missing
  }
A noattr definition must follow the equivalent attr definition.

Flags and Variables

The flags definition specifies a section of the command line that will be used to start the media tool if this plugin is matched. It can be used in attribute and format definitions and also after all the definitions are complete to finish the command line. A simple example is:
  media:audio
  proto:RTP/AVP
  tool:rat
  fmt:pcm
  {
    flags:-f pcm
  }
  fmt:dvi
  {
    flags:-f dvi
  }
  flags:-t $(TTL)
  flags:$(ADDRESS)/$(PORT)

For an rtp session with pcm format audio on address 224.2.3.4 and port 3456 with ttl 1, this would start the rat tool as follows:

  rat -f pcm -t 1 224.2.3.4/3456
As can be seen above, flags definitions can include variables that will be expanded when the session is started. As complete list of these variables is:
  • $(ADDRESS) - the address to send/recv to
  • $(PORT) - the transport port to send/recv on
  • $(TTL) - the ttl for multicast sessions
  • $(PROTO) - the value of the protocol field
  • $(FMT) - the value of the format field
  • $(SESSNAME) - the name of the session
  • $(CHAN) - the channel number for LBL's conference bus
  • $(YOUREMAIL) - the email address of the person running sdr

Macros

In cases where the value of an attribute must be passed directly to the media tool, the above mechanisms are sometimes not sufficient. To make this mechanism more flexible, sdr plugins provide a very simple macro facility. An example is:
media:audio
proto:vat
tool:vat
fmt:pcm
attr:id
{
  macro:ID
  {
    value:/$(VALUE)
  }
}
flags:$(ADDRESS)/$(PORT)$(ID)
In this case, the session attribute attribute "id" needs to be passed to vat at the end of the command line. The special variable $(VALUE) is given the value of the "id" attribute, and this is substitutes in the string given in the "value" definition. The resulting string is stored in the $(ID) variable, and expanded in the same way normal variables are when the tool is run. If there is no "id" attribute in this particular session, then the $(ID) variable is set to the empty string.

For example, a session with address/port 224.5.6.7/5432 and no id field would be started as:

vat 224.5.6.7/5432
and a session with the id atribute 1244 would have $(ID) defined as "/1234" and would be started as:
vat 224.5.6.7/5432/1234
c8@3 M@X H @t"2:|=BCJ

About Sdr

Sdr is a session directory tool designed to allow the advertisement and joining of multicast conferences on the
Mbone. It was originally based on sd written by Van Jacobson at LBNL, but implements a later version of the session description protocol than sd does. Sd and sdr are not compatible. Help is available on the following topics:

bugs and changes

Sdr was written by Mark Handley at UCL as part of the MICE and MERCI projects. Significant additions and modifications have been made by Bill Fenner at Xerox PARC and by Van Jacobson at LBNLsip recv errorWarning: 2K announcement truncated SIP announcement received (len=%d) ****VVV**** %s****^^^**** It's a request %s@%sIt's for a request for me! sip_advert%dsip_fdsip_user_alert $sip_fd $sip_advert But it's not for me :-( Call-IDFromToViaCseqpath: >%s< cseq: >%s< sip_send_unknown_user {} {} INVITE%s puts $errorInfo} OPTIONS} BYEsip_unknown_user_ack sip_send_method_unsupported } REGISTERIt's a reply Don't know what it is! Accepted new SIP TCP connection from %s on connection %d read %d bytes from connection %d connection aborted length %d bytes sip request ready callid: %s Failed to extract call id sip_success "" sip_failure sip_moved parse_sip_ringing sip_status sip_send_udp to %s/%d/%d %saddress lookup failed sip_send_udp to %s (%s) new socket couldn't get SIP socketconnectDest Address problem SO_REUSEADDRsip send ttl: %d setsockopt ttlsend: %d: res_mkqueryres_send To: t:%s@%sINVITEOPTIONSREGISTERACKBYECANCELINVITE ACK BYE CANCEL REGISTER OPTIONS SIP/2.0 rtype: %c Illegal SIP reply type couldn't get SIP receive socketbindAddress: %x, Port: %d setsockopt - IP_ADD_MEMBERSHIPfailed to create socket Port: %d listen failed! listening on port %d Accepted connection from %s content-length no CRLFCRLF in buf:>>>%s<<< len:%d clen:%d payload-buf:%d :Via:sip:No unmatched open brace in URL: %s http:ftp:mailto:gopher:news:Not a SIP URL: %s URL %s has no username ttl=transport=udptransport=tcpmaddr=tag=;v:SIP/UDPTCPreceived=branch=Invalid path: %s proto=sip, host=%s, port=%d msg=%s1: fd: %d, host: %s port: %d 2: fd: %d, host: %s port: %d sending %d butes sent %d bytes: >>>%s<<< send message on existing connection %d existing connection had been closed Unknown hostname %s socketfailed to send to fd %d port is now %d ------------------------------------------- Initiated new SIP TCP connection %d to %s seeking for call-id >>%s<< Used conn %d has callid >>%s<< this is our fd sending reply mesg: %s checking for content-length clen=%d eoh at %x, start at %x, len: %d %d-%d@%syouremailsip_server_urlREGISTER sip: SIP/2.0 Via: SIP/2.0/UDP Call-ID: To: sip: From: sip: Location: sip:@ Content-length:0 invalid SIP URL entered: %s tk_library.%d%s0-1okdupclock format [clock seconds] -format %wclock format [clock scan {%d day}] -format %%aclock format [clock scan {%d day}] -format %%Aclock scan 1/1clock format [clock scan {%d month} -base %u] -format %%hclock format [clock scan {%d month} -base %u] -format %%B-short%s@%sNONEUDPTCP"%s" "%s" "%s" %d "%s" %d "%s" "%s" "%s""%s" "%s" "%s" %d %dtcl_clitcl_pkcs7_crypttcl_pgp_crypttcl_sap_crypttcl_sdrtcl_cachetcl_sdptcl_siptcl_pluginstcl_parsed_pluginstcl_start_toolstcl_newtcl_wwwtcl_genericwrite_encryptionwrite_authenticationrun_programmake_random_keywrite_crypted_filesave_keysload_keysfind_keyname_by_keyfind_key_by_namedelete_keyadd_keyget_passphraseset_passphrasegetpidset_sipaliasui_quitsip_parse_pathsip_parse_urlsip_close_tcp_connectionsip_send_tcp_replysip_send_tcp_requestsip_send_udplookup_hostsd_listenstop_www_loadingsave_www_data_to_filewebtogetmonnamegetdaynameui_stop_session_adgetusernamegethostnamegethostaddrcheckaddresscreatesessiongetemailaddressui_generate_addressgenerate_idui_generate_portsdrUse synchronous mode for display server-syncName to use for application-nameDisplay to use-displayInitial geometry for window-geometryFile from which to read commands-file%s envDISPLAY-name sdr argvsdr:%s %s puts $errorInfotkerror {}wm geometry . setting geometryContent-Type: text/html usage: webto url [proxy] [reload] [nottcp] [argc=%d] Parse error in URL: %s Content-Type: text/html Parse error in URL helpContent-Type: text/html http/Content-Type: text/html

Unknown Host

%s does not existwebstatusConnecting...socketGET HTTP/1.0 User-agent: sdrwww sdrversion Pragma: nocache Accept: text/plain Accept: text/html Accept: image/* connectgetsockoptReceiving...updateshow_activeftpmsgpopupProtocol ErrorSorry - this browser does not yet support ftp URLsmailtoSorry - this browser does not yet support mailto URLsUnknown protocolContent-Type: text/html

Error

%s: Unknown error %d Content-Type: text/html

Error

%s: %s wcli_cmd cli_parse_commandcli_parse_command failed: %s v=resource sdrHomeDuplicate Key Register attempt: %s /keysnoneinstall_key ""install_keysomething is wrong .tmpwrtempkeybin_to_b64_aux() out of memory /keysenter_passphrasecryptrtrusteduntrustedpgpcpgpvalidpassword01validauthx509cx50AuthenticatednoauthnonevalidfileEncryptednoencsuccessDes has been successfuldes{%s}HOME%s/.sdr/data_snd.txtw%s/.sdr/data_rcv.txt%s/.sdr/data_ch.txttxtsigpgpHOME%s/.sdr/%d.%s%dwfailedpgp_cleanup pgp_create_signature recv_result1recv_authmessageAuthenticatedpgp_cleanup Signature length impossibly large:%d pgp_check_authentication recv_asym_keyidrecv_authstatusNo message was producedrcpgpcx50x509enc_pgp_cleanup pgp_create_encryption enc_pgp_cleanup recv_encmessageNo mesage were producedEncryptedpgp_check_encryption recv_encstatussuccessuccessrecv_enc_asym_keyidNo Encryption MessagetxtsigcertbtxtsymHOME%s/.sdr/%d.%s%dw cannot open %s failedpkcs7_create_signature recv_resultAuthenticatedrecv_authmessageCannot open %s pkcs7_cleanup Error writing signature to file Error writing SDP data to file pkcs7_check_authentication recv_asym_keyidrecv_authstatus The Message is empty string %s No mesage were producedrcx50x509something is wrong auth_type is not pgp or x509 authentication Header is Two big %d %d pkcs7_create_encryption 1File has not been created enc_pkcs7_cleanup recv_encmessageEncryptedenc_pkcs7_cleanup pkcs7_check_encryption recv_encstatusrecv_enc_asym_keyidThe Decryption didnot produce any message %s No Encryption Messagepgp#Copyright (c) 1995 University College London #see ui_fns.c for information on usage and redistribution of this file #and for a DISCLAIMER OF ALL WARRANTIES. proc resource {rname} { global gui if {$gui=="GUI"} { return [option get . $rname Sdr] } else { global resources return $resources($rname) } } proc set_resource {rname value} { global gui if {$gui=="GUI"} { option add $rname $value widgetDefault } else { global resources if {[string first "Sdr." $rname]==0} { set rname [string range $rname 4 end] } elseif {[string first "*" $rname]==0} { set rname [string range $rname 1 end] } set resources($rname) $value } } #sdr logging code for Louise Clark's user interface experiments set logstr "" catch { #default to logging if they're a UCL student :-) if {[string compare [string range [getusername] 0 3] "zcac"]==0} { set log TRUE } } proc log {str} { global log logstr catch { if {$log=="TRUE"} { set logstr "$logstr$str\n" } } } proc savelog {} { global logstr catch { set filename \ "/cs/research/mice/speedy/common/src/mice/sdr/sdrlog/sdrlog" set file \ [open $filename "a+" 0666 ] puts $file $logstr close $file catch {exec chmod 666 $filename} } } proc hlfocus {w} { bind $w "$w configure -background [option get . activeBackground Sdr]" bind $w "$w configure -background [option get . background Sdr]" } set tixBal(active) 1 set tixBal(popped) 0 proc tixEnableBalloon {} { global tixBal set tixBal(active) 0 } proc tixDisableBalloon {} { global tixBal set tixBal(active) 0 } proc tixBalloonAuto {} { global initWait set initWait 400 } proc tixBalloonManual {} { global initWait global tixBal if {$tixBal(popped) == 1} { tixBalPopdown } set initWait -1 } proc tixAddBalloon {w class msg {initWait 500}} { global tixBal if {$class == "Button" } { bind $w "+tkButtonEnter $w" bind $w "+tkButtonLeave $w" bind $w "+tixBalEnd $w" } else { if { $class == "Entry" } { bind $w "+tixBalEnd $w" bind $w "+focus $w" } } # bind $w <2> "+tixBalPopup $w" bind $w +[bind $class ] bind $w "+tixBalStart $w" bind $w +[bind $class ] bind $w "+tixBalEnd $w" bind $w +[bind $class ] bind $w "+catch {unset tixBal($w)}" set tixBal($w) $msg } proc tixBalStart {w} { global tixBal global initWait global last_widget if {$initWait == -1} { return } set last_widget $w after $initWait "careful_popup $w" } proc careful_popup {w} { global last_widget if {$w==$last_widget} {tixBalActivate $w} } proc tixBalEnd {w} { global tixBal global last_widget if {$w==$last_widget} {set last_widget foo} if {$tixBal(popped) == "1"} { tixBalPopdown } } proc tixBalMotion {w} { global tixBal global initWait if {$initWait == -1} { return } if {$tixBal(active) == "1" && $tixBal(popped) == 0} { incr tixBal(count) after $initWait tixBalActivate $w } } proc tixBalActivate {w} { global tixBal tixBalPopup $w } proc tixBalPopup {widget} { global tixBal set w .tix_balloon catch { toplevel $w set bg [tixQueryAppResource balloonBg TixBalloonBg #ffff60] set fg [tixQueryAppResource balloonFg TixBalloonFg black] set width [tixQueryAppResource tixBalloonWidth TixBalloonWidth 180] wm overrideredirect $w 1 message $w.msg -bg $bg -fg $fg -width $width pack $w.msg -expand yes -fill both } set x [expr [winfo rootx $widget]+[winfo width $widget]-8] set y [expr [winfo rooty $widget]+[winfo height $widget]-8] $w.msg config -text $tixBal($widget) wm geometry $w +$x+$y wm deiconify $w raise $w set tixBal(popped) 1 } proc tixBalPopdown {} { global tixBal set w .tix_balloon wm withdraw $w set tixBal(popped) 0 } proc tixQueryAppResource {name class default} { set value [resource $name] if {$value == ""} { return $default } else { return $value } } set_resource *balloonHelp 1 if { [resource balloonHelp] == 0 } { tixBalloonManual set balloonHelp 0 } else { tixBalloonAuto set balloonHelp 1 } proc set_balloon_help {mode} { if {$mode==0} { tixBalloonManual } else { tixBalloonAuto } } proc fixint {i} { if {$i == "0"} {return 0} return [string trimleft $i 0] } proc posn_win_midscreen {w} { global sizes wmoffset set x 442 set y 330 catch {set x $sizes($w.x);set y $sizes($w.y)} set sh [winfo screenheight $w] set sw [winfo screenwidth $w] set xpos [expr (($sw-$x)/2)-$wmoffset(x)] set ypos [expr (($sh-$y)/2)-$wmoffset(y)] wm geometry $w "+$xpos+$ypos" set xn [winfo rootx $w] set yn [winfo rooty $w] if {$xn>$xpos} {set wmoffset(x) [expr $xn-$xpos]} if {$yn>$ypos} {set wmoffset(y) [expr $yn-$ypos]} } proc posn_win {w} { global sizes wmoffset set x 100 set y 100 catch {set x $sizes($w.x);set y $sizes($w.y)} set geom [wm geometry .] set xpos [expr [lindex [split $geom "+x"] 2] + 25] set ypos [expr [lindex [split $geom "+x"] 3] + 25] set sh [winfo screenheight $w] set sw [winfo screenwidth $w] if {($xpos+$x+$wmoffset(x))>$sw} { set xpos [expr $xpos - (($xpos+$x+$wmoffset(x))-$sw)] } if {($ypos+$y+$wmoffset(y))>$sh} { set ypos [expr $ypos - (($ypos+$y+$wmoffset(y))-$sh)] } wm geometry $w "+$xpos+$ypos" set xn [winfo rootx $w] set yn [winfo rooty $w] if {$xn>$xpos} {set wmoffset(x) [expr $xn-$xpos]} if {$yn>$ypos} {set wmoffset(y) [expr $yn-$ypos]} } proc posn_win_rel {w main} { global sizes wmoffset set x 100 set y 100 catch {set x $sizes($w.x);set y $sizes($w.y)} set geom [wm geometry $main] set xpos [expr [lindex [split $geom "+x"] 2] + 25] set ypos [expr [lindex [split $geom "+x"] 3] + 25] set sh [winfo screenheight $w] set sw [winfo screenwidth $w] if {($xpos+$x+$wmoffset(x))>$sw} { set xpos [expr $xpos - (($xpos+$x+$wmoffset(x))-$sw)] } if {($ypos+$y+$wmoffset(y))>$sh} { set ypos [expr $ypos - (($ypos+$y+$wmoffset(y))-$sh)] } wm geometry $w "+$xpos+$ypos" } set wmoffset(x) 0 set wmoffset(y) 0 set wmoffset(is) 0 proc move_onscreen {w} { global sizes global wmoffset if {[winfo exists $w]==0} { return } update if {[winfo exists $w]==0} { return } set wh [winfo reqheight $w] set ww [winfo reqwidth $w] set sizes($w.x) $ww set sizes($w.y) $wh set sh [winfo screenheight $w] set sw [winfo screenwidth $w] set x [winfo rootx $w] set y [winfo rooty $w] set flag 0 if {($x+$ww) > $sw} { set x [expr $sw - $ww] set flag 1 } if {($y+$wh) > $sh} { set y [expr $sh - $wh] set flag 1 } if {$flag == 1} { wm geometry $w "+[expr $x-$wmoffset(x)]+[expr $y-$wmoffset(y)]" } if {($wmoffset(is)==0)&&($flag==1)} { update set nx [winfo rootx $w] set ny [winfo rooty $w] if {$nx!=$x} { set wmoffset(x) [expr $nx - $x] } if {$ny!=$y} { set wmoffset(y) [expr $ny - $y] } wm geometry $w "+[expr $x-$wmoffset(x)]+[expr $y-$wmoffset(y)]" set wmoffset(is) 1 } } proc genericpopup {ename explan title} { catch {destroy .epopup} toplevel .epopup wm title .epopup $title posn_win .epopup frame .epopup.f -relief groove -borderwidth 2 label .epopup.f.l -text $ename -font "[option get . headerFont Sdr]" message .epopup.f.m -text $explan -font "[option get . mediumFont Sdr]" -aspect 300 button .epopup.f.dismiss -text Dismiss -command "destroy .epopup" pack .epopup.f -side top pack .epopup.f.l -side top pack .epopup.f.m -side top pack .epopup.f.dismiss -side top -fill x -expand true } proc errorpopup {ename explan} { global gui if {$gui=="GUI"} { bell genericpopup $ename $explan "Sdr: [tt "Error!"]" } else { puts stderr "$ename $explan" } } proc msgpopup {ename explan} { genericpopup $ename $explan "Sdr" } proc timedmsgpopup {ename explan time} { genericpopup $ename $explan "Sdr" after $time "catch {destroy .epopup}" } proc mtk_ImbPost {w {x {}} {y {}}} { global tkPriv if {([$w.workaround configure -state] == "disabled") || ($w == $tkPriv(postedMb))} { return } set menu [$w.workaround configure -menu] if {($menu == "") || ([$menu index last] == "none")} { return } if ![string match $w.* $menu] { error "can't post $menu: it isn't a descendant of $w" } set cur $tkPriv(postedMb) if {$cur != ""} { tkMenuUnpost {} } # set tkPriv(cursor) [$w.workaround configure -cursor] set tkPriv(relief) [$w.workaround configure -relief] # $w configure -cursor arrow $w configure -relief raised set tkPriv(postedMb) $w set tkPriv(focus) [focus] $menu activate none # If this looks like an option menubutton then post the menu so # that the current entry is on top of the mouse. Otherwise post # the menu just below the menubutton, as for a pull-down. $menu post [winfo rootx $w] [expr [winfo rooty $w]+[winfo height $w]] focus $menu tkSaveGrabInfo $w grab -global $w bind $w {mtk_ImbUnpost {} } bind $w {mtk_ImbUnpost {} } } proc mtk_ImbUnpost menu { global tkPriv set mb $tkPriv(postedMb) # Restore focus right away (otherwise X will take focus away when # the menu is unmapped and under some window managers (e.g. olvwm) # we'll lose the focus completely). catch {focus $tkPriv(focus)} set tkPriv(focus) "" # Unpost menu(s) and restore some stuff that's dependent on # what was posted. catch { if {$mb != ""} { set menu [$mb.workaround configure -menu] $menu unpost set tkPriv(postedMb) {} $mb configure -cursor $tkPriv(cursor) $mb configure -relief $tkPriv(relief) } elseif {$tkPriv(popup) != ""} { $tkPriv(popup) unpost set tkPriv(popup) {} } elseif {[wm overrideredirect $menu]} { # We're in a cascaded sub-menu from a torn-off menu or popup. # Unpost all the menus up to the toplevel one (but not # including the top-level torn-off one) and deactivate the # top-level torn off menu if there is one. while 1 { set parent [winfo parent $menu] if {([winfo class $parent] != "Menu") || ![winfo ismapped $parent]} { break } $parent activate none $parent postcascade none if {![wm overrideredirect $parent]} { break } set menu $parent } $menu unpost } } # Release grab, if any, and restore the previous grab, if there # was one. if {$menu != ""} { set grab [grab current $menu] if {$grab != ""} { grab release $grab } } catch { if {$tkPriv(oldGrab) != ""} { if {$tkPriv(grabStatus) == "global"} { grab set -global $tkPriv(oldGrab) } else { grab set $tkPriv(oldGrab) } set tkPriv(oldGrab) "" } } } proc iconbutton {args} { set name [lindex $args 0] global $name set [set name](state) normal set borderwidth 2 set relief flat set command "" set text "" set bitmap "" set menu "" set width "" set font "" set pad 1 for {set i 1} {$i < [llength $args]} {incr i} { case [lindex $args $i] in { "-borderwidth" {set borderwidth [lindex $args [expr $i+1]];incr i} "-text" {set text [lindex $args [expr $i+1]];incr i} "-bitmap" {set bitmap [lindex $args [expr $i+1]];incr i} "-relief" {set relief [lindex $args [expr $i+1]];incr i} "-command" {set command [lindex $args [expr $i+1]];incr i} "-width" {set width [lindex $args [expr $i+1]];incr i} "-menu" {set menu [lindex $args [expr $i+1]];incr i} "-font" {set font [lindex $args [expr $i+1]];incr i} "-pad" {set pad [lindex $args [expr $i+1]];incr i} "-state" {set [set name](state) [lindex $args [expr $i+1]];incr i} default {puts "Unknown option [lindex $args $i] to iconbutton $name"} } } frame $name -relief flat -borderwidth 0 frame $name.f -relief $relief -borderwidth $borderwidth pack $name.f -side top -fill both label $name.f.bm -bitmap $bitmap -borderwidth 0 pack $name.f.bm -side left -fill y -ipady 2 label $name.f.text -text $text -borderwidth 0 -pady $pad if {$width!=""} {$name.f.text configure -width $width} if {$font!=""} {$name.f.text configure -font $font} pack $name.f.text -side left -fill both -expand true -ipady $pad bind $name.f.bm \ "highlight_iconbutton $name [option get . activeBackground Sdr]" bind $name.f.text \ "highlight_iconbutton $name [option get . activeBackground Sdr]" if {$menu==""} { bind $name.f.bm \ "$name.f configure -relief sunken;pack_iconbits $name" bind $name.f.text \ "$name.f configure -relief sunken;pack_iconbits $name" bind $name.f.bm \ "$name.f configure -relief $relief;pack_iconbits $name;$command" bind $name.f.text \ "$name.f configure -relief $relief;pack_iconbits $name;$command" bind $name.f.bm \ "highlight_iconbutton $name [option get . background Sdr]" bind $name.f.text \ "highlight_iconbutton $name [option get . background Sdr]" } else { bind $name.f.bm \ "mtk_ImbPost $name" bind $name.f.text \ "mtk_ImbPost $name" bind $name.f.bm \ "highlight_iconbutton $name [option get . background Sdr]" bind $name.f.text \ "highlight_iconbutton $name [option get . background Sdr]" } proc $name.workaround {args} [format { global %s # puts $args case [lindex $args 0] in { {config configure} { if {[llength $args]==2} { case [lindex $args 1] in { "-relief" {return [%s.f config -relief]} "-state" {set st [set %s(state)];return "$st"} "-menu" {return "%s"} } } else { set ix 1 while {$ix < [llength $args]} { case [lindex $args $ix] in { "-relief" { %s.f configure -relief \ [lindex $args [expr $ix + 1]] } "-state" { set %s(state) [lindex $args [expr $ix + 1]] case [lindex $args [expr $ix + 1]] in { normal { %s.f.bm configure -foreground \ [option get . foreground Sdr] %s.f.text configure -foreground \ [option get . foreground Sdr] } disabled { %s.f.bm configure -foreground \ [option get . disabledForeground Sdr] %s.f.text configure -foreground \ [option get . disabledForeground Sdr] } } } } incr ix 2 } } } } } $name $name $name $menu $name $name $name $name $name $name] } proc highlight_iconbutton {name col} { global $name if {[set [set name](state)]!="disabled"} { $name.f.bm configure -background $col $name.f.text configure -background $col } } proc pack_iconbits {name} { #shouldn't need this, but there's a bug in the packer... pack $name.f.bm -side left pack $name.f.text -side left -fill both -expand true } proc password {args} { if {[llength $args] < 1} { return } set win [lindex $args 0] set width 10 set relief sunken set borderwidth 2 set background [option get . background Sdr] set font [option get . font Sdr] set variable "" set command break set ix 2 foreach a [lrange $args 1 end] { case $a in { "-width" { set width [lindex $args $ix] } "-relief" { set relief [lindex $args $ix] } "-background" { set background [lindex $args $ix] } "-borderwidth" { set borderwidth [lindex $args $ix] } "-variable" { set variable [lindex $args $ix] } "-font" {set font [lindex $args $ix] } "-command" {set command [lindex $args $ix] } } incr ix } entry $win -width $width \ -background $background \ -borderwidth $borderwidth \ -relief $relief \ -font $font \ -highlightthickness 0 global $variable set $variable "" bind $win "add_password_char $win $variable %A;break" bind $win "del_password_char $win $variable;break" bind $win "del_password_char $win $variable;break" bind $win $command bind $win {focus [tk_focusNext %W];break} bind $win {focus [tk_focusPrev %W];break} proc $win.workaround {args} [format { if {[lindex $args 0]=="set"} { set_password_chars %s %s [lindex $args 1] } } $win $variable] } proc set_password_chars {win var chs} { global $var set $var $chs $win delete 0 end for {set i 0} {$i < [string length $chs]} {incr i} { $win insert 0 "*" } } proc add_password_char {win var ch} { global $var set v [set $var] if {[is_printable $ch]} { set v "$v$ch" $win insert end "*" $win icursor end set $var $v } } proc del_password_char {win var} { global $var set v [set $var] set last [expr [string length $v] - 2] set v [string range $v 0 $last] $win delete 0 1 set $var $v } proc is_printable {ch} { if {[string length $ch]==1} { scan $ch %c c if {$c < 32} { return 0 } return 1 } return 0 } set urilist {} set uriix -1 set cacheduris {} set cachedata {} option add Sdr.web.h1font "-*-times-bold-r-normal--*-240-*" widgetDefault option add Sdr.web.h2font "-*-times-bold-r-normal--*-180-*" widgetDefault option add Sdr.web.h3font "-*-times-bold-r-normal--*-140-*" widgetDefault option add Sdr.web.h4font "-*-times-bold-r-normal--*-140-*" widgetDefault option add Sdr.web.bfont "-*-times-bold-r-normal--*-140-*" widgetDefault option add Sdr.web.ifont "-*-times-medium-i-normal--*-140-*" widgetDefault option add Sdr.web.addressfont "-*-times-medium-i-normal--*-140-*" widgetDefault option add Sdr.web.normalfont "-*-times-medium-r-normal--*-140-*" widgetDefault option add Sdr.web.prefont "-*-courier-medium-r-normal--*-120-*" widgetDefault proc webdisp {uri} { global urilist uriix catch { toplevel .web frame .web.f -borderwidth 2 -relief groove pack .web.f -side top -fill both -expand true text .web.f.c -width 80 -height 30 -wrap word \ -font [option get .web prefont Sdr]\ -yscroll ".web.f.sb set" pack .web.f.c -side left -fill both -expand true scrollbar .web.f.sb -command ".web.f.c yview" \ -background [option get . scrollbarBackground Sdr] #TBD # -foreground [option get . scrollbarForeground Sdr] \ # -activeforeground [option get . scrollbarActiveForeground Sdr] pack .web.f.sb -side right -fill y frame .web.f0 -borderwidth 2 -relief groove pack .web.f0 -side top -fill x for {set i 0} {$i<5} {incr i} { frame .web.f0.active$i -width 5 -height 10 -bg white pack .web.f0.active$i -side left } label .web.f0.l -text "Status:" pack .web.f0.l -side left set webstatus "Looking up address" label .web.f0.s -text $webstatus -anchor w pack .web.f0.s -side left -anchor w -fill x -expand true frame .web.f1 -borderwidth 2 -relief groove pack .web.f1 -side top -fill x label .web.f1.l -text "Location:" pack .web.f1.l -side left entry .web.f1.e -width 40 -relief sunken -borderwidth 2 bind .web.f1.e { webdisp [.web.f1.e get] } pack .web.f1.e -side left -fill x -expand true frame .web.f2 -borderwidth 2 -relief groove pack .web.f2 -side top -fill x button .web.f2.back -text Back \ -command {incr uriix -1; webdisp2} pack .web.f2.back -side left -fill x -expand true button .web.f2.forw -text Forward \ -command {incr uriix; webdisp2} pack .web.f2.forw -side left -fill x -expand true button .web.f2.reload -text Reload \ -command {webdisp2 r} pack .web.f2.reload -side left -fill x -expand true button .web.f2.stop -text Stop -command {stop_www_loading} pack .web.f2.stop -side left -fill x -expand true button .web.f2.dismiss -text Dismiss \ -command {stop_www_loading; destroy .web} pack .web.f2.dismiss -side left -fill x -expand true set uriix -1 set urilist {} } # If there's no colon, or if the colon is followed by a port number and # potentially a pathname, then add the missing "http://" . if {[string first ":" $uri]==-1 || [regexp {^[^:]+:[0-9]+(|/.*)$} $uri]} { set uri "http://$uri" } set urilist [lrange $urilist 0 $uriix] lappend urilist $uri incr uriix catch {webdisp2} } # webdisp2 only ever displays $urilist[$uriix] proc webdisp2 {{reload {}}} { global urilist uriix webproxy webstatus cacheduris cachedata if {$uriix==-1} { puts "webdisp2 called with no url" return } set webstatus "Looking up address" .web.f0.s configure -text $webstatus update .web.f2.stop configure -state normal if {$uriix==0} { .web.f2.back configure -state disabled } else { .web.f2.back configure -state normal } if {$uriix<[expr [llength $urilist]-1]} { .web.f2.forw configure -state normal } else { # Range checking if {$uriix>[expr [llength $urilist] -1]} { puts "webdisp2 had to reset uriix" set uriix [expr [llength $urilist] -1] } .web.f2.forw configure -state disabled } set uri [lindex $urilist $uriix] set cacheix [lsearch $cacheduris $uri] if {$cacheix == -1 || $reload != {}} { set str [webto $uri $webproxy $reload] if {[string length $str] < 10000} { if {$cacheix == -1} { if {[llength $cacheduris] > 20} { set cacheduris [lrange $cacheduris 1 end] set cachedata [lrange $cachedata 1 end] } lappend cacheduris $uri lappend cachedata $str } else { set cachedata [lreplace $cachedata $cacheix $cacheix $str] } } } else { set str [lindex $cachedata $cacheix] } .web.f2.stop configure -state disabled set webstatus "Parsing" .web.f0.s configure -text $webstatus show_inactive update # puts "uriix=$uriix" # puts "urilist=$urilist" .web.f1.e delete 0 end .web.f1.e insert 0 $uri .web.f.c configure -state normal .web.f.c delete 1.0 end wm title .web "WWW browser" #parse the header # # Some bonehead web servers forget to reply with HTTP 1.0 headers # in certain situations. Guess using bogus heuristic: if {[string index $str 0]=="<"} { set header "Content-type: text/html\n" set data $str } else { set hend [string first "\r\n\r\n" $str] # puts $hend if {$hend==-1} { set hend [string first "\n\n" $str] if {$hend==-1} { puts "Failed to find CRLFCRLF or LFLF in header!" puts [split [string range $str 0 400] "\n"] set data "Failed to find CRLFCRLF or LFLF in header!" } else { set data [string range $str [expr $hend + 2] end] } } else { set data [string range $str [expr $hend + 4] end] } set header [string range $str 0 $hend] } set ctype text set cstype html set hlist [split $header "\n"] set redirect 0 foreach h $hlist { set h [string trim $h "\r"] set field [string tolower [lindex [split $h ":"] 0]] set value [string trim [lindex [split $h ":"] 1] " "] # puts "->$field<->$value<-" if {$field == "content-type"} { set ctype [lindex [split $value "/"] 0] set cstype [lindex [split $value "/"] 1] } elseif {$field == "location"} { set redirect \ [string trim [join [lrange [split $h ":"] 1 end] ":"] " "] } } if {$redirect != 0} { set urilist [lreplace $urilist $uriix $uriix $redirect] webdisp2 return } if {$ctype != "text"} { if {$ctype=="image"} { msgpopup "Starting external viewer" "Data is an image" save_www_data_to_file [expr $hend + 4] /tmp/sdrimage exec xv /tmp/sdrimage & } else { # Server CERN/3.0pre6 uses content-type "www/unknown" # for error messages! How to handle this?? msgpopup "Invalid Content Type" "$ctype/$cstype is not a text type" set webstatus "Finished" .web.f0.s configure -text $webstatus return } } if {$cstype == "plain"} { # We need to use prefont to set the width properly, but we want to default # to normalfont. Is there a better way to do this? .web.f.c tag configure hack -font [option get .web normalfont Sdr] .web.f.c tag add hack 1.0 end .web.f.c insert 1.0 $data highlight_url .web.f.c 1 .web.f.c configure -state disabled } elseif {$cstype=="html"} { parse_html .web.f.c $data if {[regexp {#(.*)$} $uri junk anchor]} { set anchor "M$anchor" catch {.web.f.c yview $anchor} } } set webstatus "Finished" .web.f0.s configure -text $webstatus wm minsize .web 1 1 } proc webstatus {} { global webstatus #the things we do to get around broken Tcl_Eval calls! .web.f0.s configure -text $webstatus } set statctr 0 proc show_active {} { global statctr .web.f0.active$statctr configure -background white incr statctr if {$statctr==5} {set statctr 0} .web.f0.active$statctr configure -background blue } proc show_inactive {} { global statctr .web.f0.active$statctr configure -background white } proc overhref {{href {}}} { global webstatus if {$href == {}} { .web.f0.s configure -text $webstatus } else { set width [winfo width .web.f0.s] .web.f0.s configure -text $href #trim the string until it fits... set reqwidth [winfo reqwidth .web.f0.s] while {$width<$reqwidth} { set href [string range $href 0 [expr [string length $href]-2]] .web.f0.s configure -text $href set reqwidth [winfo reqwidth .web.f0.s] } } } proc parse_html {win data} { global uriix urilist href set type normal set ptype normal set normal normal set ltype ul set href 0 set refnum 0 set break 1 set space 2 set listindent 0 set bulletnum 0 set fontstack normal foreach tag {h1 h2 h3 h4 b i address normal pre} { $win tag configure $tag -font [option get .web ${tag}font Sdr] } $win tag configure ref -foreground blue $win tag configure dd -lmargin1 40 -lmargin2 40 $win tag configure center -justify center $win insert end " " $win tag add normal 1.0 end regsub -all "\r\n" $data "\n" data # Some web servers violate HTTP and send \r-seperated lines regsub -all "\r" $data "\n" data while {$data!=""} { # puts [string length $data] set ix1 [string first "<" $data] set cur [$win index "end - 1 chars"] if {$type=="title"} { wm title .web [string range $data 0 [expr $ix1-1]] } else { set idata [string range $data 0 [expr $ix1-1]] if {$break==1} { set llist [split $idata "\n\r"] set idata "" foreach line $llist { if {$line!=""} { if {$idata==""} { # Note that source HTML like # # foo # blah # # will get rendered like # # foo blah # # because of the following if. # if {$space>0} { set line [string trimleft $line " \t"] } set idata $line } else { set line [string trimleft $line " \t"] set idata "$idata $line" } } } } if {([string trim $idata " \t"]!="")||($break==0)} { $win insert end [parse_for_escaped_chars $idata] set space 0 } $win tag remove $ptype $cur end $win tag add $type $cur end update set ptype $type if {$href!=0} { $win tag configure ref$refnum -foreground blue $win tag bind ref$refnum <1> \ "webdisp {$href}" $win tag bind ref$refnum \ "$win tag configure ref$refnum -foreground \ [option get . activehotForeground Sdr];\ overhref {$href}" $win tag bind ref$refnum \ "$win tag configure ref$refnum -foreground \ [option get . hotForeground Sdr];\ overhref" $win tag add ref$refnum $cur end } else { $win tag remove ref$refnum $cur end } } set ix2 [string first ">" $data] set tag [string range $data [expr $ix1+1] [expr $ix2-1]] if {$ix2!=-1} { set data [string range $data [expr $ix2+1] end] } else { $win insert end [parse_for_escaped_chars $data] $win configure -state disabled return } set tname [lindex [split $tag " \n\r\t"] 0] set tname [string tolower $tname] set cur [$win index "end - 1 chars"] if {$tname=="base"} { set base [parseref $tag] if {$base != 0} { .web.f1.e delete 0 end .web.f1.e insert 0 $base set urilist [lreplace $urilist $uriix $uriix $base] } } elseif {$tname=="meta"} { # People seem to tend to use # # instead of document redirects. ARGH! # # Technically, this really should pretend that it's just another # header & the header parser should be expanded, but this is the # easy 90% case! if {[parsestr $tag "http-equiv" equiv] && $equiv=="Refresh"} { if [parsestr $tag "content" content] { if {[parsestr $content "url" newurl] && $newurl != {}} { regexp {^([0-9]+);} $content foo delay # puts "Refresh after $delay seconds to $newurl" if {$delay == 0} { set urilist [lreplace $urilist $uriix $uriix $newurl] webdisp2 return } else { after [expr $delay*1000] webrefresh $newurl \ [lindex $urilist $uriix] } } } } } elseif {$tname=="p"} { set space [addspace $win 2 $space] rmtags $win $cur end set data [string trimleft $data " "] } elseif {$tname=="hr"} { addspace $win 2 $space $win insert end "--------\n" set space 1 set data [string trimleft $data " "] } elseif {$tname=="a"} { set href [fixuri [parseref $tag]] if [parsestr $tag "name" mark] { set mark "M$mark" $win mark set $mark $cur $win mark gravity $mark left } # set space 0 incr refnum } elseif {$tname=="/a"} { set href 0 } elseif {$tname=="address"} { set space [addspace $win 1 $space] set type $tname } elseif {$tname=="/address"} { set type $normal } elseif {$tname=="h1"} { set space [addspace $win 2 $space] set type $tname set data [string trimleft $data " "] set fontstack h1 } elseif {$tname=="h2"} { set space [addspace $win 2 $space] set type $tname set data [string trimleft $data " "] set fontstack h2 } elseif {$tname=="h3"} { set space [addspace $win 2 $space] set type $tname set data [string trimleft $data " "] set fontstack h3 } elseif {$tname=="h4"} { set space [addspace $win 2 $space] set type $tname set data [string trimleft $data " "] set fontstack h3 } elseif {$tname=="/h1"} { set space [addspace $win 2 $space] set type $normal set data [string trimleft $data " "] set fontstack normal } elseif {$tname=="/h2"} { set space [addspace $win 2 $space] set type $normal set data [string trimleft $data " "] set fontstack normal } elseif {$tname=="/h3"} { set space [addspace $win 2 $space] set type $normal set data [string trimleft $data " "] set fontstack normal } elseif {$tname=="/h4"} { set space [addspace $win 2 $space] set type $normal set data [string trimleft $data " "] set fontstack normal } elseif {$tname=="br" || $tname=="/br"} { # Sigh, netscape treats
as
so people will use it set space [addspace $win 1 $space] set data [string trimleft $data " "] } elseif {$tname=="img"} { #is there an alternate text string if [parsestr $tag "alt" alt] { $win insert end $alt } else { #is it an active map (can't do them!) set ix [string first "ismap" [string tolower $tag]] if {$ix!=-1} { set href 0 $win insert end "\[ACTIVE MAP\]" } else { $win insert end "\[IMAGE\]" } } rmtags $win $cur end if {$href!=0} { $win tag add ref$refnum $cur end $win tag configure ref$refnum -foreground blue $win tag bind ref$refnum <1> \ "webdisp $href" } set space 0 } elseif {$tname=="dl"} { set space [addspace $win 2 $space] set type $normal set ltype dl incr listindent } elseif {$tname=="/dl"} { set space [addspace $win 2 $space] set type $normal set ltype ul incr listindent -1 } elseif {$tname=="dt"} { set space [addspace $win 2 $space] set type $normal } elseif {$tname=="dd"} { set space [addspace $win 1 $space] set type $tname } elseif {$tname=="ul"} { set space [addspace $win 2 $space] set type $normal set ltype ul incr listindent } elseif {$tname=="/ul"} { set space [addspace $win 2 $space] set type $normal set ltype ul incr listindent -1 } elseif {$tname=="menu"} { set space [addspace $win 2 $space] set type $normal set ltype ul incr listindent } elseif {$tname=="/menu"} { set space [addspace $win 2 $space] set type $normal set ltype ul incr listindent -1 } elseif {$tname=="ol"} { set space [addspace $win 2 $space] set type $normal set ltype ol set lnum 1 incr listindent } elseif {$tname=="/ol"} { set space [addspace $win 2 $space] set type $normal set ltype ul incr listindent -1 } elseif {$tname=="li"} { set space [addspace $win 1 $space] for {set ind 1} {$ind < $listindent} {incr ind} { $win insert end " " } if {$ltype=="ul"} { if {$listindent==1} { $win window create end -create "label $win.bullet$bulletnum -bitmap bullet0" incr bulletnum } else { $win window create end -create "label $win.bullet$bulletnum -bitmap bullet1" incr bulletnum } rmtags $win $cur end set data [string trimleft $data " \n\t\r"] } elseif {$ltype=="ol"} { $win insert end " $lnum. " rmtags $win $cur end set data [string trimleft $data " \n\t\r"] incr lnum } } elseif {$tname=="/b"} { if {[lindex $fontstack 0]=="b"} { set type normal catch { set type [lindex $fontstack 1] set fontstack [lrange $fontstack 1 end] } } else { set type normal } # set space 0 } elseif {$tname=="/i"} { if {[lindex $fontstack 0]=="i"} { set type normal catch { set type [lindex $fontstack 1] set fontstack [lrange $fontstack 1 end] } } else { set type normal } # set space 0 } elseif {$tname=="pre"} { set type $tname set break 0 set space [addspace $win 1 0] set fontstack pre } elseif {$tname=="/pre"} { set type normal set break 1 set space [addspace $win 1 0] set fontstack normal } elseif {$tname=="!"} { # do anything here, or just completely ignore? } elseif {$tname=="!doctype"} { # do nothing. } elseif {[string match "!--*" $tname]} { # A comment may have embedded HTML; if the end of the tag # is not "--" then find the real end tag. # Note that this doesn't parse "" $data] if {$cix != -1} { set data [string range $data [expr $cix+3] end] } } } elseif {$tname=="b"} { set type $tname if {[lindex $fontstack 0]!="b"} { set fontstack "b $fontstack" } } elseif {$tname=="i"} { set type $tname if {[lindex $fontstack 0]!="i"} { set fontstack "i $fontstack" } } elseif {$tname=="form"} { start_form $tag } elseif {$tname=="/form"} { end_form } elseif {$tname=="input"} { form_input $tag $win } elseif {$tname=="select"} { form_start_select $tag $win } elseif {$tname=="/select"} { form_end_select $win } elseif {$tname=="option"} { form_select_option $tag $win } elseif {$tname=="textarea"} { form_start_textarea $tag $win } elseif {$tname=="/textarea"} { form_end_textarea $win } else { set type $tname # set space 0 } } $win configure -state disabled } set form 0 proc start_form {tag} { global form subform incr form set subform 0 } proc end_form {} { global form } proc form_input {tag win} { global form subform incr subform set bits [split $tag "\""] set str "" set eo 0 foreach bit $bits { if {$eo==1} { set str $str[join [split $bit] {\ }] set eo 0 } else { set str $str$bit set eo 1 } } puts $str # set bits [split $str " "] set name "" set type "" set value "" set checked 0 set size 8 foreach bit $str { puts "bit: $bit" set attr [string tolower [lindex [split $bit "="] 0]] set val [lindex [split $bit "="] 1] switch $attr { type { set type $val } name { set name $val } value { set value $val } size { set size $val } checked { set checked 1 } } } puts "type: $type name: $name value: $value" switch $type { submit { $win window create end -create "button $win.w$form,$subform -text \"$value\"" } reset { $win window create end -create "button $win.w$form,$subform -text \"$value\"" } text { $win window create end -create "entry $win.w$form,$subform" } radio { $win window create end -create "radiobutton $win.w$form,$subform -variable formradio($form,$name) -value \"$value\"" if {$checked==1} { global formradio set formradio($form,$name) "$value" } } } } proc form_start_select {tag win} { global form subform incr subform set bits [split $tag " "] set name "" set value "" set size 3 foreach bit $bits { set attr [string tolower [lindex [split $bit "="] 0]] set val [string trim [lindex [split $bit "="] 1] "\""] switch $attr { name { set name $val } value { set value $val } size { set size $val } } } frame $win.w$form,$subform listbox $win.w$form,$subform.lb -height $size \ -yscroll "$win.w$form,$subform.sb set" pack $win.w$form,$subform.lb -side left scrollbar $win.w$form,$subform.sb -command "$win.w$form,$subform.lb yview" pack $win.w$form,$subform.sb -side right -fill y -expand true $win window create end -window $win.w$form,$subform } proc form_end_select {win} { global form subform } proc form_select_option {tag win} { global form subform } proc form_start_textarea {tag win} { global form subform incr subform set bits [split $tag " "] set name "" set value "" set rows 3 set cols 40 foreach bit $bits { set attr [string tolower [lindex [split $bit "="] 0]] set val [string trim [lindex [split $bit "="] 1] "\""] switch $attr { name { set name $val } value { set value $val } rows { set rows $val } cols { set cols $val } } } frame $win.w$form,$subform text $win.w$form,$subform.ta -height $rows -width $cols \ -yscroll " $win.w$form,$subform.sb set" pack $win.w$form,$subform.ta -side left scrollbar $win.w$form,$subform.sb -command "$win.w$form,$subform.ta yview" pack $win.w$form,$subform.sb -side right -fill y -expand true $win window create end -window $win.w$form,$subform } proc form_end_textarea {win} { } proc addspace {win num space} { set cur [$win index "end - 1 chars"] while {$num > $space} { $win insert end "\n" incr space } rmtags $win $cur end return $space } proc gohome {} { global home uriix urilist webdisp $home } proc rmtags {win p1 p2} { set tlist [$win tag names $p1] foreach t $tlist { $win tag remove $t $p1 $p2 } $win tag add normal $p1 $p2 } proc parseref {ref} { if {[parsestr $ref "href" tmp]==0} { return 0 } else { return $tmp } } # parsestr returns the value for a particular key/value pair # attempting to allow optional quoting and the always-forgotten # trailing quote. # # parsestr returns the value in the variable $ret, and returns # 1 if it found a match or 0 if it failed. # # XXX todo: remove regexp special characters from $key proc parsestr {str key ret} { if {[regexp -nocase "^(.*\[ \t\r\n]+)?${key}\[ \t\r\n=]+(.*)$" $str \ junk junk2 str]==0} {uplevel "set $ret {}"; return 0} if {[regexp {^"([^"]*)"?} $str junk tmp]} { uplevel "set $ret {$tmp}" } else { uplevel "set $ret {[lindex [split $str] 0]}" } return 1 } proc webrefresh {newurl cururl} { global uriix urilist if {$cururl != [lindex $urilist $uriix]} { # puts "Refreshing from $cururl to $newurl failed because we're on [lindex $urilist $uriix] now" # We're not currently on the page that the refresh belongs to return } else { # puts "Refreshing from $cururl to $newurl" # If it's a different URL, then add it to the history # If it's the same URL, just re-display it if [string compare $cururl $newurl] { webdisp $newurl } else { webdisp2 } } } proc getprevuri {} { global uriix urilist # put $urilist return [lindex $urilist [expr $uriix-1]] } proc getnexturi {} { global uriix urilist # puts $urilist if {[llength $urilist] > $uriix} { return [lindex $urilist [expr $uriix+1]] } else { return [lindex $urilist $uriix] } } proc fixuri {uri} { global uriix urilist if {$uri==0} {return 0} set ix [string first "://" $uri] if {$ix > -1} { if {[string index $uri 0]!="/"} { return $uri } } if {[string range $uri 0 4]=="help:"} {return $uri} if {[string range $uri 0 6]=="mailto:"} {return $uri} #break up the current url set cururi [lindex [split [lindex $urilist $uriix] "#"] 0] set ix [string first "://" $cururi] set proto [string range $cururi 0 [expr $ix-1]] set host [string range $cururi [expr $ix+3] end] set ix [string first "/" $host] if {$ix!=-1} { set path [string range $host [expr $ix+1] end] set host [string range $host 0 [expr $ix-1]] } else { set path "" } # Have to parse host-less URL's like http:/foo/bar/baz #there's no protocol field present if {[lindex [split $uri "#"] 0]==""} { #it's in the same file return "$cururi$uri" } elseif {[string index $uri 0]!="/"} { #it's a relative filename set dropctr 1 while {[string range $uri 0 2]=="../"} { incr dropctr set uri [string range $uri 3 end] } set plist [split $path "/"] set plist [lrange $plist 0 [expr [llength $plist]-($dropctr+1)]] lappend plist $uri set path [join $plist "/"] return "$proto://$host/$path" } elseif {[string index $uri 1]!="/"} { #it's an absolute filename return "$proto://$host$uri" } else { #only the proto is missing return "$proto:$uri" } } proc parse_for_escaped_chars {data} { set result "" while {[string first "&" $data]!=-1} { set ix [string first "&" $data] set result $result[string range $data 0 [expr $ix-1]] set data [string range $data $ix end] set ix2 [string first ";" $data] if {$ix2 == -1} { break; } set esc [string range $data 0 $ix2] set data [string range $data [expr $ix2+1] end] switch -regexp $esc { {^"$} {set result "$result''"} {^Æ$} {set result [format "%s%c" $result 198]} {^Á$} {set result [format "%s%c" $result 193]} {^Â$} {set result [format "%s%c" $result 194]} {^À$} {set result [format "%s%c" $result 192]} {^Å$} {set result [format "%s%c" $result 197]} {^Ã$} {set result [format "%s%c" $result 195]} {^Ä$} {set result [format "%s%c" $result 196]} {^Ç$} {set result [format "%s%c" $result 199]} {^Ð$} {set result [format "%s%c" $result 208]} {^É$} {set result [format "%s%c" $result 201]} {^Ê$} {set result [format "%s%c" $result 202]} {^È$} {set result [format "%s%c" $result 200]} {^Ë$} {set result [format "%s%c" $result 203]} {^Í$} {set result [format "%s%c" $result 205]} {^Î$} {set result [format "%s%c" $result 206]} {^Ì$} {set result [format "%s%c" $result 204]} {^Ï$} {set result [format "%s%c" $result 207]} {^Ñ$} {set result [format "%s%c" $result 209]} {^Ó$} {set result [format "%s%c" $result 211]} {^Ô$} {set result [format "%s%c" $result 212]} {^Ò$} {set result [format "%s%c" $result 210]} {^Ø$} {set result [format "%s%c" $result 216]} {^Õ$} {set result [format "%s%c" $result 213]} {^Ö$} {set result [format "%s%c" $result 214]} {^Þ$} {set result [format "%s%c" $result 222]} {^Ú$} {set result [format "%s%c" $result 218]} {^Û$} {set result [format "%s%c" $result 219]} {^Ù$} {set result [format "%s%c" $result 217]} {^Ü$} {set result [format "%s%c" $result 220]} {^Ý$} {set result [format "%s%c" $result 221]} {^á$} {set result [format "%s%c" $result 225]} {^â$} {set result [format "%s%c" $result 226]} {^´$} {set result [format "%s%c" $result 180]} {^æ$} {set result [format "%s%c" $result 230]} {^à$} {set result [format "%s%c" $result 224]} {^&$} {set result [format "%s%c" $result 38]} {^å$} {set result [format "%s%c" $result 229]} {^ã$} {set result [format "%s%c" $result 227]} {^ä$} {set result [format "%s%c" $result 228]} {^¦$} {set result [format "%s%c" $result 166]} {^ç$} {set result [format "%s%c" $result 231]} {^¸$} {set result [format "%s%c" $result 184]} {^¢$} {set result [format "%s%c" $result 162]} {^©$} {set result [format "%s%c" $result 169]} {^¤$} {set result [format "%s%c" $result 164]} {^°$} {set result [format "%s%c" $result 176]} {^÷$} {set result [format "%s%c" $result 247]} {^é$} {set result [format "%s%c" $result 233]} {^ê$} {set result [format "%s%c" $result 234]} {^è$} {set result [format "%s%c" $result 232]} {^ð$} {set result [format "%s%c" $result 240]} {^ë$} {set result [format "%s%c" $result 235]} {^½$} {set result [format "%s%c" $result 189]} {^¼$} {set result [format "%s%c" $result 188]} {^¾$} {set result [format "%s%c" $result 190]} {^>$} {set result [format "%s%c" $result 62]} {^í$} {set result [format "%s%c" $result 237]} {^î$} {set result [format "%s%c" $result 238]} {^¡$} {set result [format "%s%c" $result 161]} {^ì$} {set result [format "%s%c" $result 236]} {^¿$} {set result [format "%s%c" $result 191]} {^ï$} {set result [format "%s%c" $result 239]} {^«$} {set result [format "%s%c" $result 171]} {^<$} {set result [format "%s%c" $result 60]} {^¯$} {set result [format "%s%c" $result 175]} {^µ$} {set result [format "%s%c" $result 181]} {^·$} {set result [format "%s%c" $result 183]} {^ $} {set result [format "%s%c" $result 32]} {^¬$} {set result [format "%s%c" $result 172]} {^ñ$} {set result [format "%s%c" $result 241]} {^ó$} {set result [format "%s%c" $result 243]} {^ô$} {set result [format "%s%c" $result 244]} {^ò$} {set result [format "%s%c" $result 242]} {^ª$} {set result [format "%s%c" $result 170]} {^º$} {set result [format "%s%c" $result 186]} {^ø$} {set result [format "%s%c" $result 248]} {^õ$} {set result [format "%s%c" $result 245]} {^ö$} {set result [format "%s%c" $result 246]} {^¶$} {set result [format "%s%c" $result 182]} {^±$} {set result [format "%s%c" $result 177]} {^£$} {set result [format "%s%c" $result 163]} {^»$} {set result [format "%s%c" $result 187]} {^®$} {set result [format "%s%c" $result 174]} {^§$} {set result [format "%s%c" $result 167]} {^­$} {set result [format "%s%c" $result 173]} {^¹$} {set result [format "%s%c" $result 185]} {^²$} {set result [format "%s%c" $result 178]} {^³$} {set result [format "%s%c" $result 179]} {^ß$} {set result [format "%s%c" $result 223]} {^þ$} {set result [format "%s%c" $result 254]} {^×$} {set result [format "%s%c" $result 215]} {^ú$} {set result [format "%s%c" $result 250]} {^û$} {set result [format "%s%c" $result 251]} {^ù$} {set result [format "%s%c" $result 249]} {^¨$} {set result [format "%s%c" $result 168]} {^ü$} {set result [format "%s%c" $result 252]} {^ý$} {set result [format "%s%c" $result 253]} {^¥$} {set result [format "%s%c" $result 165]} {^ÿ$} {set result [format "%s%c" $result 255]} {^&#[0-9]+;$} {regexp {0*([0-9]+)} $esc junk tmp set result [format "%s%c" $result $tmp]} default {set result [format "%s%c" $result 38] set data [string range $esc 1 end]$data} } } set result $result$data return $result } #new.tcl Copyright (c) 1995 University College London #see ui_fns.c for information on usage and redistribution of this file #and for a DISCLAIMER OF ALL WARRANTIES. #If you need to add more panels, create a function called #new_wiz_panel_XYZ, and add XYZ to these lists in the order you want it #called. set new_wiz_norm_panels \ "info type timing_norm scope_norm media_norm contact accept" set new_wiz_tech_panels \ "info type timing_tech scope_tech media_tech contact accept" proc new {aid} { global ifstyle ldata if {[string compare $aid "new"]!=0} { #we need a working variable while we think about editing sessions, #in case we don't commit the changes. set ldata($aid,tmpmulticast) $ldata($aid,multicast) } new_wiz_init $aid $ifstyle(create) } proc new_wiz_init {aid iftype} { global new_wiz_norm_panels new_wiz_tech_panels global send new_createtime medialist ldata catch {destroy .new} toplevel .new wm title .new "Session Creation Wizard" frame .new.f -borderwidth 2 -relief groove pack .new.f -side top -fill both -expand true label .new.f.l -text "" pack .new.f.l -side top -fill x text .new.f.t -width 80 -height 5 -relief flat -highlightthickness 0 \ -wrap word pack .new.f.t -side top frame .new.f.f -borderwidth 2 -relief groove pack .new.f.f -side top -fill x frame .new.f.f.spacer -width 1 -height 200 -borderwidth 0 pack .new.f.f.spacer -side right frame .new.f.b -borderwidth 2 -relief groove pack .new.f.b -side top -fill x button .new.f.b.back -text "<< Back" -command "" -relief raised \ -borderwidth 1 -highlightthickness 0 -state disabled pack .new.f.b.back -side left -fill x -expand true button .new.f.b.next -text "Next >>" -command "" -relief raised \ -borderwidth 1 -highlightthickness 0 -state disabled pack .new.f.b.next -side left -fill x -expand true button .new.f.b.accept -text "Accept" \ -relief raised \ -borderwidth 1 -highlightthickness 0 pack .new.f.b.accept -side left -fill x -expand true button .new.f.b.cancel -text "Cancel" -command {destroy .new} \ -relief raised \ -borderwidth 1 -highlightthickness 0 pack .new.f.b.cancel -side left -fill x -expand true if {[string compare $aid "new"]!=0} { wm title .new "Sdr: [tt "Edit Session"]" foreach i $medialist { set send($i) 0 } set new_createtime $ldata($aid,createtime) } else { wm title .new "Sdr: [tt "Create New Session"]" foreach i $medialist { set send($i) 0 } set send(audio) 1 set new_createtime [unix_to_ntp [gettimeofday]] } if {$iftype=="tech"} { eval "new_wiz_panel_[lindex $new_wiz_tech_panels 0] 0 \"$new_wiz_tech_panels\" $aid" } else { eval "new_wiz_panel_[lindex $new_wiz_norm_panels 0] 0 \"$new_wiz_norm_panels\" $aid" } } proc new_wiz_change_panels {} { .new.f.t configure -state normal .new.f.t delete 1.0 end set children [winfo children .new.f.f] foreach child $children { pack unpack $child } pack .new.f.f.spacer -side right } proc new_wiz_panel_info {panelnum panels aid} { new_wiz_change_panels .new.f.l configure -text "Step $panelnum: Information About the Session" .new.f.t insert 1.0 "You need to give a title to your session and provide information about it. The information should be a paragraph or so describing the purpose of the session. If you need to refer people to more information, add a URL below. The URL can be left blank, but the title and information must be given. When you've filled in this information, click on Next." set next_panel [expr $panelnum + 1] .new.f.t configure -state disabled .new.f.b.next configure -state normal -command "new_wiz_panel_[lindex $panels $next_panel] $next_panel \"$panels\" $aid" .new.f.b.back configure -state disabled .new.f.b.accept configure -state disabled new_mk_session_name .new.f.f $aid new_mk_session_desc .new.f.f $aid new_mk_session_url .new.f.f $aid } proc new_wiz_panel_type {panelnum panels aid} { new_wiz_change_panels .new.f.l configure -text "Step $panelnum: What Type of Session is this?" .new.f.t insert 1.0 "You need to specify the type of session. Use \"broadcast\" for sessions that are largely non-interactive, \"meeting\" for interactive sessions and private meetings, and \"test\" for anything that isn't intended for real listeners." .new.f.t configure -state disabled set next_panel [expr $panelnum + 1] set back_panel [expr $panelnum - 1] .new.f.b.next configure -state normal -command "new_wiz_panel_[lindex $panels $next_panel] $next_panel \"$panels\" $aid" .new.f.b.back configure -state normal -command "new_wiz_panel_[lindex $panels $back_panel] $back_panel \"$panels\" $aid" .new.f.b.accept configure -state disabled new_mk_session_type .new.f.f.type top $aid } proc new_wiz_panel_timing_norm {panelnum panels aid} { global ldata new_wiz_change_panels .new.f.l configure -text "Step $panelnum: When will the session be active?" .new.f.t insert 1.0 "You need to configure when the session will be active so people will know when to join it. For example, if the session is active on Monday and Thursday each week for four weeks, configure Monday's start time and duration in the first row, Thursday's start time and duration in the second row, set both to be \"Weekly\" and configure \"Repeat for\" to be \"4 weeks\"." .new.f.t configure -state disabled set next_panel [expr $panelnum + 1] set back_panel [expr $panelnum - 1] .new.f.b.next configure -state normal -command "new_wiz_panel_[lindex $panels $next_panel] $next_panel \"$panels\" $aid" .new.f.b.back configure -state normal -command "new_wiz_panel_[lindex $panels $back_panel] $back_panel \"$panels\" $aid" if {[winfo exists .new.f.f.f2]==0} { frame .new.f.f.f2 frame .new.f.f.f2.act -relief groove -borderwidth 2 frame .new.f.f.f2.act.l label .new.f.f.f2.act.l.icon -bitmap clock label .new.f.f.f2.act.l.l -text "Session will take place ..." tixAddBalloon .new.f.f.f2.act.l.l Label [tt "When and how often is the session going to be on"] global rpt_times global has_times global needs_lifetime global rpt_min_values global rpt_menu_value global duration_max set rpt_times {{---} {Once} {Daily} {Weekly} {Every Two Weeks}\ {Monthly by Date} {Monday thru Friday}} #whether or not the times box should be active set has_times {0 1 1 1 1 1 1} set menu_disabled {0 0 0 0 0 1 1} #whether or not there is a repeat time set needs_lifetime {0 0 1 1 1 1 1} #what the default minimum repeat time should be set rpt_min_values {0 0 2880 20160 40320 40320 20160} #what the max duration should be for each repeat interval set duration_max {0 4838400 43200 518400 1036800 0 604800} if {[string compare $aid "new"]!=0} { for {set box 1} {$box <= $ldata($aid,no_of_times)} { incr box} { set rpt_menu_value($box) 1 new_mk_session_time_box .new.f.f.f2.act $box $ldata($aid,no_of_times) $rpt_times $menu_disabled } } else { set rpt_menu_value(1) 1 new_mk_session_time_box .new.f.f.f2.act 1 1 $rpt_times $menu_disabled } label .new.f.f.f2.act.expl2 -text [tt "Length of this series of sessions"] \ -font [resource infoFont] frame .new.f.f.f2.act.fd label .new.f.f.f2.act.fd.l -text [tt "Repeat for:"] duration_widget .new.f.f.f2.act.fd.duration 3600 if {[string compare $aid "new"]!=0} { configure_duration_box .new.f.f.f2.act.fd $ldata($aid,no_of_times) } else { configure_duration_box .new.f.f.f2.act.fd 1 } if {[string compare $aid "new"]!=0} { set rpts 0 set maxdiff 0 for {set t 0} {$t < $ldata($aid,no_of_times)} {incr t} { if {$ldata($aid,time$t,no_of_rpts)==0} { .new.f.f.f2.act.fb[expr $t+1].day.workaround configure \ -time $ldata($aid,starttime,$t) .new.f.f.f2.act.fb[expr $t+1].time.workaround configure \ -time $ldata($aid,starttime,$t) .new.f.f.f2.act.fb[expr $t+1].duration.workaround configure -time \ [expr $ldata($aid,endtime,$t) - $ldata($aid,starttime,$t)] set rpt_menu_value([expr $t+1]) 1 configure_rpt_menu [expr $t+1] .new.f.f.f2.act.fb[expr $t+1] } else { set rpts 1 for {set r 0} {$r < $ldata($aid,time$t,no_of_rpts)} {incr r} { if {$r>0} {puts "too complicated - tragic!"} if {$ldata($aid,time$t,offset$r)!="0"} { puts "too many offsets! - tragic!" } set start $ldata($aid,starttime,$t) set end $ldata($aid,endtime,$t) set dur $ldata($aid,time$t,duration$r) set ofs $ldata($aid,time$t,offset$r) if {[expr ($end-$start)-$dur]> $maxdiff } { set maxdiff [expr ($end-$start)-$dur] } .new.f.f.f2.act.fb[expr $t+1].day.workaround configure -time $start .new.f.f.f2.act.fb[expr $t+1].time.workaround configure -time $start .new.f.f.f2.act.fb[expr $t+1].duration.workaround configure -time $dur case $ldata($aid,time$t,interval$r) in { 86400 {set rpt_menu_value([expr $t+1]) 2} 604800 { if {$ofs=="0"} { set rpt_menu_value([expr $t+1]) 3 } elseif {$ofs=="0 86400 172800 259200 345600"} { set rpt_menu_value([expr $t+1]) 6 } else { puts "help - can't handle this weekly offset" } } 1209600 {set rpt_menu_value([expr $t+1]) 4} } configure_rpt_menu [expr $t+1] .new.f.f.f2.act.fb[expr $t+1] } } } if {$rpts==1} { .new.f.f.f2.act.fd.duration.workaround configure -time $maxdiff .new.f.f.f2.act.fd.duration.workaround configure -state normal } } } pack .new.f.f.f2 -side top -pady 5 -fill x -expand true pack .new.f.f.f2.act -side left -fill both -expand true pack .new.f.f.f2.act.l -side top -anchor w pack .new.f.f.f2.act.l.icon -side left pack .new.f.f.f2.act.l.l -side left pack .new.f.f.f2.act.expl2 -side top -anchor w pack .new.f.f.f2.act.fd -side top -anchor w pack .new.f.f.f2.act.fd.l -side left -anchor w } proc new_wiz_panel_timing_tech {panelnum panels aid} { global ldata new_wiz_change_panels .new.f.l configure -text "Step $panelnum: When will the session be active?" .new.f.t insert 1.0 "You need to configure when the session will be active so people will know when to join it. For example, if the session is active on Monday and Thursday each week for four weeks, configure Monday's start time and duration in the first row, Thursday's start time and duration in the second row, set both to be \"Weekly\" and configure \"Repeat for\" to be \"4 weeks\"." .new.f.t configure -state disabled set next_panel [expr $panelnum + 1] set back_panel [expr $panelnum - 1] .new.f.b.next configure -state normal -command "new_wiz_panel_[lindex $panels $next_panel] $next_panel \"$panels\" $aid" .new.f.b.back configure -state normal -command "new_wiz_panel_[lindex $panels $back_panel] $back_panel \"$panels\" $aid" global rpt_times global has_times global needs_lifetime global rpt_min_values global rpt_menu_value global duration_max set rpt_times {{---} {Once} {Daily} {Weekly} {Every Two Weeks}\ {Monthly by Date} {Monday thru Friday}} #whether of not the times box should be active set has_times {0 1 1 1 1 1 1} set menu_disabled {0 0 0 0 0 1 1} #whether or not there is a repeat time set needs_lifetime {0 0 1 1 1 1 1} #what the default minimum repeat time should be set rpt_min_values {0 0 2880 20160 40320 40320 20160} #what the max duration should be for each repeat interval set duration_max {0 4838400 43200 518400 1036800 0 604800} set rpt_menu_value(1) 1 set rpt_menu_value(2) 0 set rpt_menu_value(3) 0 if {[winfo exists .new.f.f.f2]==0} { frame .new.f.f.f2 label .new.f.f.f2.l -text "Session will be active:" frame .new.f.f.f2.act -relief groove -borderwidth 2 foreach box {1 2 3} { new_mk_session_time_box .new.f.f.f2.act $box 3 $rpt_times $menu_disabled } frame .new.f.f.f2.act.fd label .new.f.f.f2.act.fd.l -text "Repeat for:" duration_widget .new.f.f.f2.act.fd.duration 3600 configure_duration_box .new.f.f.f2.act.fd 3 if {[string compare $aid "new"]!=0} { set rpts 0 set maxdiff 0 for {set t 0} {$t < $ldata($aid,no_of_times)} {incr t} { if {$ldata($aid,time$t,no_of_rpts)==0} { .new.f.f.f2.act.fb[expr $t+1].day.workaround configure \ -time $ldata($aid,starttime,$t) .new.f.f.f2.act.fb[expr $t+1].time.workaround configure \ -time $ldata($aid,starttime,$t) .new.f.f.f2.act.fb[expr $t+1].duration.workaround configure -time \ [expr $ldata($aid,endtime,$t) - $ldata($aid,starttime,$t)] set rpt_menu_value([expr $t+1]) 1 configure_rpt_menu [expr $t+1] .new.f.f.f2.act.fb[expr $t+1] } else { set rpts 1 for {set r 0} {$r < $ldata($aid,time$t,no_of_rpts)} {incr r} { if {$r>0} {puts "too complicated - tragic!"} if {$ldata($aid,time$t,offset$r)!="0"} { puts "too many offsets! - tragic!" } set start $ldata($aid,starttime,$t) set end $ldata($aid,endtime,$t) set dur $ldata($aid,time$t,duration$r) set ofs $ldata($aid,time$t,offset$r) if {[expr ($end-$start)-$dur]> $maxdiff } { set maxdiff [expr ($end-$start)-$dur] } .new.f.f.f2.act.fb[expr $t+1].day.workaround configure -time $start .new.f.f.f2.act.fb[expr $t+1].time.workaround configure -time $start .new.f.f.f2.act.fb[expr $t+1].duration.workaround configure -time $dur case $ldata($aid,time$t,interval$r) in { 86400 {set rpt_menu_value([expr $t+1]) 2} 604800 { if {$ofs=="0"} { set rpt_menu_value([expr $t+1]) 3 } elseif {$ofs=="0 86400 172800 259200 345600"} { set rpt_menu_value([expr $t+1]) 6 } else { puts "help - can't handle this weekly offset" } } 1209600 {set rpt_menu_value([expr $t+1]) 4} } configure_rpt_menu [expr $t+1] .new.f.f.f2.act.fb[expr $t+1] } } } if {$rpts==1} { .new.f.f.f2.act.fd.duration.workaround configure -time $maxdiff .new.f.f.f2.act.fd.duration.workaround configure -state normal } } } pack .new.f.f.f2 -side top pack .new.f.f.f2.l -side top pack .new.f.f.f2.act -side left -fill both -expand true pack .new.f.f.f2.act.fd -side top -anchor w pack .new.f.f.f2.act.fd.l -side left -anchor w } proc new_wiz_panel_scope_norm {panelnum panels aid} { new_wiz_change_panels .new.f.l configure -text "Step $panelnum: Select the Distibution Scope" .new.f.t insert 1.0 "You need to decide how far away you wish the traffic from this session to be received. You can set this using TTL scoping or Admin Scoping. TTL Scoping is the old method - we recommend Admin Scoping." .new.f.t configure -state disabled set next_panel [expr $panelnum + 1] set back_panel [expr $panelnum - 1] .new.f.b.next configure -state normal -command "new_wiz_panel_[lindex $panels $next_panel] $next_panel \"$panels\" $aid" .new.f.b.back configure -state normal -command "new_wiz_panel_[lindex $panels $back_panel] $back_panel \"$panels\" $aid" .new.f.b.accept configure -state disabled new_mk_session_norm_scope .new.f.f $aid } proc new_wiz_panel_scope_tech {panelnum panels aid} { new_wiz_change_panels .new.f.l configure -text "Step $panelnum: Select the Distibution Scope" .new.f.t insert 1.0 "You need to decide how far away you wish the traffic from this session to be received. You can set this using TTL scoping or Admin Scoping. TTL Scoping is the old method - we recommend Admin Scoping." .new.f.t configure -state disabled set next_panel [expr $panelnum + 1] set back_panel [expr $panelnum - 1] .new.f.b.next configure -state normal -command "new_wiz_panel_[lindex $panels $next_panel] $next_panel \"$panels\" $aid" .new.f.b.back configure -state normal -command "new_wiz_panel_[lindex $panels $back_panel] $back_panel \"$panels\" $aid" .new.f.b.accept configure -state disabled new_mk_session_tech_scope .new.f.f $aid } proc new_wiz_panel_media_norm {panelnum panels aid} { global scope new_wiz_change_panels .new.f.l configure -text "Step $panelnum: Choose and configure the media?" .new.f.t insert 1.0 "You need to decide which media the session will use. For each medium, you need to choose the protocol and format. Some formats also let you choose the number of layers in the encoding." .new.f.t configure -state disabled set next_panel [expr $panelnum + 1] set back_panel [expr $panelnum - 1] .new.f.b.next configure -state normal -command "new_wiz_panel_[lindex $panels $next_panel] $next_panel \"$panels\" $aid" .new.f.b.back configure -state normal -command "new_wiz_panel_[lindex $panels $back_panel] $back_panel \"$panels\" $aid" set show_details 0 new_mk_session_media .new.f.f.media $aid $scope $show_details } proc new_wiz_panel_media_tech {panelnum panels aid} { global scope new_wiz_change_panels .new.f.l configure -text "Step $panelnum: Choose and configure the media?" .new.f.t insert 1.0 "You need to decide which media the session will use. For each medium, you need to choose the protocol and format. Some formats also let you choose the number of layers in the encoding." .new.f.t configure -state disabled set next_panel [expr $panelnum + 1] set back_panel [expr $panelnum - 1] .new.f.b.next configure -state normal -command "new_wiz_panel_[lindex $panels $next_panel] $next_panel \"$panels\" $aid" .new.f.b.back configure -state normal -command "new_wiz_panel_[lindex $panels $back_panel] $back_panel \"$panels\" $aid" set show_details 1 new_mk_session_media .new.f.f.media $aid $scope $show_details } proc new_wiz_panel_contact {panelnum panels aid} { global scope new_wiz_change_panels .new.f.l configure -text "Step $panelnum: Provide Contact Details" .new.f.t insert 1.0 "You need to provide contact details for the session so that people can get in touch if there is a problem." .new.f.t configure -state disabled set next_panel [expr $panelnum + 1] set back_panel [expr $panelnum - 1] .new.f.b.next configure -state normal -command "new_wiz_panel_[lindex $panels $next_panel] $next_panel \"$panels\" $aid" .new.f.b.back configure -state normal -command "new_wiz_panel_[lindex $panels $back_panel] $back_panel \"$panels\" $aid" .new.f.b.accept configure -state disabled new_mk_session_contact .new.f.f.you $aid } proc new_wiz_panel_accept {panelnum panels aid} { global scope new_wiz_change_panels .new.f.l configure -text "Review session details" .new.f.t insert 1.0 "Check the details below are correct. If they are correct, press \"Accept\". If they're incorrect, go back and amend the information. \"Cancel\" will abort and lose any information you've entered." .new.f.t configure -state disabled set next_panel [expr $panelnum + 1] set back_panel [expr $panelnum - 1] .new.f.b.next configure -state disabled .new.f.b.accept configure -state normal -command \ "if {\[create\]==1} \ {destroy .new}" .new.f.b.back configure -state normal -command "new_wiz_panel_[lindex $panels $back_panel] $back_panel \"$panels\" $aid" new_mk_session_accept .new.f.f.accept .new.f.f $aid } proc new_mk_session_accept {win base aid} { global ldata if {[winfo exists $win]==0} { frame $win frame $win.r1 pack $win.r1 -side top -anchor w label $win.r1.l1 -text "Title:" pack $win.r1.l1 -side left label $win.r1.l2 pack $win.r1.l2 -side left label $win.r1.l3 -text "Type:" pack $win.r1.l3 -side left label $win.r1.l4 pack $win.r1.l4 -side left frame $win.r2 pack $win.r2 -side top -anchor w label $win.r2.l1 -text "Description:" pack $win.r2.l1 -side left -anchor nw text $win.r2.m -width 65 -height 1 -relief flat -borderwidth 1 \ -highlightthickness 0 pack $win.r2.m -side left frame $win.r3 pack $win.r3 -side top -anchor w label $win.r3.l1 -text "URL for more info:" pack $win.r3.l1 -side left label $win.r3.l2 pack $win.r3.l2 -side left frame $win.r4 pack $win.r4 -side top -anchor w text $win.r4.m -width 80 -height 1 -relief flat -borderwidth 1 \ -highlightthickness 0 pack $win.r4.m -side left frame $win.r5 pack $win.r5 -side top -anchor w label $win.r5.l1 -text "Email:" pack $win.r5.l1 -side left label $win.r5.l2 pack $win.r5.l2 -side left label $win.r5.l3 -text "Phone:" pack $win.r5.l3 -side left label $win.r5.l4 pack $win.r5.l4 -side left frame $win.r6 pack $win.r6 -side top -anchor w label $win.r6.l1 -text "Session Scope:" pack $win.r6.l1 -side left label $win.r6.l2 pack $win.r6.l2 -side left frame $win.r7 pack $win.r7 -side top -anchor w text $win.r7.m -width 80 -height 1 -relief flat -borderwidth 1 \ -highlightthickness 0 -wrap none pack $win.r7.m -side left } pack $win -side top -fill x set title [get_new_session_name $base] if {$title!=""} { $win.r1.l2 configure -text $title \ -foreground [option get . foreground Sdr] } else { $win.r1.l2 configure -text "TITLE MISSING" -foreground red } global sess_type $win.r1.l4 configure -text $sess_type set desc [get_new_session_desc] if {$desc!=""} { set lines [expr 1+[string length $desc]/65] $win.r2.m configure -foreground [option get . foreground Sdr] \ -state normal -height $lines $win.r2.m delete 1.0 end $win.r2.m insert 1.0 $desc $win.r2.m configure -state disabled } else { $win.r2.m configure -foreground red -state normal $win.r2.m delete 1.0 end $win.r2.m insert 1.0 "DESCRIPTION MISSING" $win.r2.m configure -state disabled } set url [get_new_session_uri] if {$url!=""} { $win.r3.l2 configure -text $url } else { $win.r3.l2 configure -text "no url given" } set email [.new.f.f.you.f0.e get] $win.r5.l2 configure -text $email set phone [.new.f.f.you.f1.e get] $win.r5.l4 configure -text $phone set no_of_times 0 set ldata(new,starttime) 0 set ldata(new,stoptime) 0 foreach i {1 2 3} { #the catch is here because the simple i/f only has one time entry catch { set tmp [get_expiry_time .new.f.f.f2.act.fb$i $i .new.f.f.f2.act.fd.duration] if {[lindex $tmp 0]!=0} { set starttime [ntp_to_unix [lindex $tmp 0]] set stoptime [ntp_to_unix [lindex $tmp 1]] set ldata(new,starttime,$no_of_times) $starttime set ldata(new,tfrom,$no_of_times) \ [clock format $starttime -format {%d %b %y %H:%M %Z}] set ldata(new,stoptime,$no_of_times) $stoptime set ldata(new,tto,$no_of_times) \ [clock format $stoptime -format {%d %b %y %H:%M %Z}] if {($starttime < $ldata(new,starttime)) || \ ($ldata(new,starttime)==0)} { set ldata(new,starttime) $starttime set ldata(new,tfrom) test1 } if {($stoptime > $ldata(new,stoptime)) } { set ldata(new,stoptime) $stoptime set ldata(new,tto) test2 } if {[lindex $tmp 2]!=0} { set ldata(new,time$no_of_times,no_of_rpts) 1 set ldata(new,time$no_of_times,interval0) \ [lindex $tmp 2] set ldata(new,time$no_of_times,duration0) \ [lindex $tmp 3] set ldata(new,time$no_of_times,offset0) \ [lindex $tmp 4] # set sess "$sess\nr=[lrange $tmp 2 end]" } else { set ldata(new,time$no_of_times,no_of_rpts) 0 } incr no_of_times } } } set ldata(new,no_of_times) $no_of_times set timing [text_times_english new] regsub "\n" $timing " " timing set lines [expr 1+[string length $timing]/80] $win.r4.m configure -state normal -height $lines $win.r4.m delete 1.0 end $win.r4.m insert 1.0 $timing $win.r4.m configure -state disabled global zone scope if {$scope=="admin"} { $win.r6.l2 configure -text $zone(name,$zone(cur_zone)) } else { $win.r6.l2 configure -text "TTL [get_ttl_scope] scoped" } set ms "Media:" global medialist send media_proto media_fmt media_layers media_attr set ctr 1 foreach media $medialist { if {$send($media)==1} { incr ctr set ms "$ms\n $media:" set ms "$ms proto [get_proto_name $media_proto($media)]" set ms "$ms, fmt [get_fmt_name $media_fmt($media)]" if {$media_layers($media)>1} { set ms "$ms, $media_layers($media) layers" } set ms "$ms, [get_new_session_addr $media]/[get_new_session_port $media]" set attrs "" foreach attr [array names media_attr] { set m [lindex [split $attr ","] 0] set a [lindex [split $attr ","] 1] if {$m==$media} { if {$media_attr($attr)==1} { set attrs "$attrs $a" } elseif {($media_attr($attr)!=0)&&\ ($media_attr($attr)!="")} { set attrs "$attrs $a:$media_attr($attr)" } } } set attrs [string trimleft $attrs] if {$attrs!=""} { set ms "$ms, $attrs" } } } $win.r7.m configure -state normal -height $ctr $win.r7.m delete 1.0 end $win.r7.m insert 1.0 $ms $win.r7.m configure -state disabled } proc set_sess_type {win type} { global sess_type set sess_type $type switch $type { test { $win.m configure -text Test } broadcast { $win.m configure -text Broadcast } meeting { $win.m configure -text Meeting } #secure { # $win.m configure -text Secure #} other { $win.m configure -text Unspecified } } } proc new_mk_session_norm_scope {win aid} { global zone scope ldata if {[winfo exists $win.f3]==0} { if {[string compare $aid "new"]!=0} { set sap_addr $ldata($aid,sap_addr) set ttl $ldata($aid,ttl) set scope ttl set zone(cur_zone) $zone(ttl_scope) for {set i 0} {$i<$zone(no_of_zones)} {incr i} { # puts "$zone(sap_addr,$i)==$sap_addr)&&($zone(ttl,$i)==$ttl)" if {($zone(sap_addr,$i)==$sap_addr)&&($zone(ttl,$i)==$ttl)} { # puts "setting zone(cur_zone) $i" set scope admin set zone(cur_zone) $i } } } else { set scope admin set zone(cur_zone) 0 set ttl $zone(ttl,$zone(cur_zone)) } frame $win.f3 frame $win.f3.m -width 1 -height 1 frame $win.f3.m2 -width 1 -height 1 } pack $win.f3 -side top -pady 5 pack $win.f3.m -side left -fill y -padx 3 pack $win.f3.m2 -side left -fill y -padx 3 new_mk_session_admin $win.f3.admin $aid $scope } proc new_mk_session_tech_scope {win aid} { global zone scope new_ttl ldata medialist send if {[winfo exists $win.f3]==0} { if {[string compare $aid "new"]!=0} { set sap_addr $ldata($aid,sap_addr) set ttl $ldata($aid,ttl) set scope ttl set zone(cur_zone) $zone(ttl_scope) for {set i 0} {$i<$zone(no_of_zones)} {incr i} { if {($zone(sap_addr,$i)==$sap_addr)&&($zone(ttl,$i)==$ttl)} { set scope admin set zone(cur_zone) $i break } } for {set mnum 0} {$mnum < $ldata($aid,medianum)} {incr mnum} { set send($ldata($aid,$mnum,media)) 1 } } else { set scope admin set zone(cur_zone) 0 set ttl $zone(ttl,$zone(cur_zone)) } frame $win.f3 frame $win.f3.r label $win.f3.r.l2 -text "Scope Mechanism:" radiobutton $win.f3.r.b3 -text "TTL Scope" \ -highlightthickness 0 \ -variable scope -value ttl -relief flat -command \ [format { set addr [generate_address %s] if {$addr!=0} { pack %s.f3.rr -after %s.f3.m2 -side left -fill both \ -expand true pack forget %s.f3.admin if {$addr!=1} { foreach media $medialist { if {$send($media)==1} { store_new_session_addr $media [generate_address] } } } set zone(cur_zone) $zone(ttl_scope) set scope ttl set_ttl_scope %s $ttl } else { set scope admin } } $aid $win $win $win $win] radiobutton $win.f3.r.b4 -text "Admin Scope" \ -highlightthickness 0 \ -variable scope -value admin -relief flat -command \ [format { # Recover the previously-selected scope if one clicks # on "admin" then "ttl" then "admin". # set tmpzone 0 for {set i 0} {$i < $zone(no_of_zones)} {incr i} { if {[string compare \ [%s.f3.admin.f.lb tag cget line$i -background] \ [option get . activeBackground Sdr]]==0} { set tmpzone $i break } } set addr [generate_address $zone(base_addr,$tmpzone) \ $zone(netmask,$tmpzone) %s] if {$addr!=0} { set zone(cur_zone) $tmpzone pack %s.f3.admin -after %s.f3.m2 -side left -fill both \ -expand true pack forget %s.f3.rr if {$addr!=1} { foreach media $medialist { if {$send($media)==1} { store_new_session_addr $media \ [generate_address \ $zone(base_addr,$zone(cur_zone)) \ $zone(netmask,$zone(cur_zone))] } } } set scope admin set ttl $zone(ttl,$zone(cur_zone)) } else { set scope ttl } unset tmpzone } $win $aid $win $win $win] hlfocus $win.f3.r.b3 hlfocus $win.f3.r.b4 #padding frame frame $win.f3.m2 -width 1 -height 1 #admin scope frame frame $win.f3.admin -relief groove -borderwidth 2 label $win.f3.admin.l -text Scope: frame $win.f3.admin.f -relief sunken -borderwidth 1 text $win.f3.admin.f.lb -width 15 -height 6 -relief flat -wrap none for {set i 0} {$i < $zone(no_of_zones)} {incr i} { $win.f3.admin.f.lb insert [expr $i+1].0 "$zone(name,$i)" $win.f3.admin.f.lb tag add line$i [expr $i+1].0 end-1c $win.f3.admin.f.lb tag configure line$i -background\ [option get . background Sdr] $win.f3.admin.f.lb insert end " \n" $win.f3.admin.f.lb tag bind line$i <1> \ [format { set addr [generate_address $zone(base_addr,%s) \ $zone(netmask,%s) %s] if {$addr!=0} { #the change of scope is OK for {set i 0} {$i < $zone(no_of_zones)} {incr i} { %s.f3.admin.f.lb tag configure line$i -background\ [option get . background Sdr] } %s.f3.admin.f.lb tag configure line%s -background\ [option get . activeBackground Sdr] set ttl $zone(ttl,%s) if {$addr!=1} { #and we can reallocated the addresses too. foreach media $medialist { if {$send($media)==1} { store_new_session_addr $media \ [generate_address $zone(base_addr,%s) \ $zone(netmask,%s)] } } } set zone(cur_zone) %s } } $i $i $aid $win $win $i $i $i $i $i] } $win.f3.admin.f.lb configure -state disabled $win.f3.admin.f.lb tag configure line$zone(cur_zone) -background\ [option get . activeBackground Sdr] frame $win.f3.rr -relief groove -borderwidth 2 tixAddBalloon $win.f3.rr Frame [tt "The scope determines how far your session will reach. The default values are: Local net: 1 Site: 15 Region: 63 World: 127 Specify the smallest scope that will reach the people you want to communicate with."] label $win.f3.rr.l -text [tt "Scope"] radiobutton $win.f3.rr.r1 -relief flat -text [tt "Site"] -variable ttl\ -highlightthickness 0 \ -value 15 -command {disable_scope_entry 15} radiobutton $win.f3.rr.r2 -relief flat -text [tt "Region"] -variable ttl\ -highlightthickness 0 \ -value 63 -command {disable_scope_entry 63} radiobutton $win.f3.rr.r3 -relief flat -text [tt "World"] -variable ttl\ -highlightthickness 0 \ -value 127 -command {disable_scope_entry 127} hlfocus $win.f3.rr.r1 hlfocus $win.f3.rr.r2 hlfocus $win.f3.rr.r3 frame $win.f3.rr.f if {[string compare $aid "new"]==0} { radiobutton $win.f3.rr.f.r4 -relief flat -variable ttl\ -highlightthickness 0 \ -command "enable_scope_entry 1" -value 0 } else { radiobutton $win.f3.rr.f.r4 -relief flat -variable ttl\ -highlightthickness 0 \ -command "enable_scope_entry $ttl" -value 0 } entry $win.f3.rr.f.e -relief sunken -width 4 -text 1 \ -bg [option get . entryBackground Sdr] \ -highlightthickness 0 $win.f3.rr.f.e insert 0 $ttl proc disable_scope_entry {value} [format { %s.f3.rr.f.e configure -state normal %s.f3.rr.f.e delete 0 end %s.f3.rr.f.e insert 0 $value %s.f3.rr.f.e configure -state disabled \ -background [option get . background Sdr]\ -relief groove } $win $win $win $win ] proc enable_scope_entry {ttl} [format { %s.f3.rr.f.e configure -state normal \ -background [option get . entryBackground Sdr]\ -relief sunken %s.f3.rr.f.e delete 0 end %s.f3.rr.f.e insert 0 $ttl } $win $win $win ] proc get_ttl_scope {} [format { return [%s.f3.rr.f.e get] } $win ] bind $win.f3.rr.f.e <1> [format { %s.f3.rr.f.r4 invoke %s.f3.rr.f.e icursor end focus %s.f3.rr.f.e } $win $win $win ] if {[string compare $aid "new"]!=0} { set ttl $ldata($aid,ttl) if {$scope=="ttl"} { set_ttl_scope $win $ttl } } else { if {$scope=="ttl"} { $win.f3.rr.r1 invoke } } } pack $win.f3 -side top pack $win.f3.r -side left pack $win.f3.r.l2 -side top -anchor nw pack $win.f3.r.b3 -side top -anchor nw pack $win.f3.r.b4 -side top -anchor nw pack $win.f3.m2 -side left -fill y -padx 3 pack $win.f3.admin.l -side top -anchor w pack $win.f3.admin.f -side top -fill both -expand true pack $win.f3.admin.f.lb -side top -fill both -expand true pack $win.f3.rr.f.r4 -side left pack $win.f3.rr.f.e -side left pack $win.f3.rr.l -side top -anchor w pack $win.f3.rr.r1 -side top -anchor w pack $win.f3.rr.r2 -side top -anchor w pack $win.f3.rr.r3 -side top -anchor w pack $win.f3.rr.f -side top -anchor w if {$scope=="admin"} { pack unpack $win.f3.rr pack $win.f3.admin -side left -fill both -expand true } if {$scope=="ttl"} { pack unpack $win.f3.rr pack $win.f3.rr -side left -fill both -expand true } } proc new_mk_session_type {win order aid} { global ldata typelist if {[winfo exists $win]==0} { frame $win label $win.l -text "Type of Session:" menubutton $win.m -menu $win.m.menu -width 10\ -borderwidth 1 -relief raised menu $win.m.menu -tearoff 0 foreach type $typelist { $win.m.menu add command -label [get_type_name $type] \ -command "set_sess_type $win $type" } if {[string compare $aid "new"]==0} { set_sess_type $win test } else { set_sess_type $win $ldata($aid,type) } } pack $win -side top pack $win.l -side $order -anchor nw pack $win.m -side $order -anchor nw -padx 10 } proc new_mk_session_name {win aid} { global ldata if {[winfo exists $win.f0]==0} { frame $win.f0 label $win.f0.l -text [tt "Session Name:"] entry $win.f0.entry -width 30 -relief sunken\ -bg [option get . entryBackground Sdr] \ -highlightthickness 0 tixAddBalloon $win.f0.entry Entry [tt "Enter the name of the session here"] if {[string compare $aid "new"]!=0} { $win.f0.entry insert 0 $ldata($aid,session) } proc get_new_session_name {win} { $win.f0.entry get } } pack $win.f0.l -side left pack $win.f0.entry -side left -fill x -expand true pack $win.f0 -side top -anchor w -fill x } proc new_mk_session_desc {win aid} { global ldata if {[winfo exists $win.descl]==0} { label $win.descl -text [tt "Description:"] frame $win.df text $win.df.desc -width 40 -height 5 -relief sunken -borderwidth 2 \ -bg [option get . entryBackground Sdr] \ -yscroll "$win.df.sb set"\ -wrap word scrollbar $win.df.sb -command "$win.df.desc yview" \ -background [option get . scrollbarBackground Sdr] \ -borderwidth 1 -relief flat #TBD # -foreground [option get . scrollbarForeground Sdr] \ # -activeforeground [option get . scrollbarActiveForeground Sdr] tixAddBalloon $win.df.desc Text [tt "Enter a short description of your session here"] #this shouldn't really list the widgets by name bind $win.df.desc "focus $win.url.f0.e;break" bind $win.df.desc "focus $win.f0.entry;break" if {[string compare $aid "new"]!=0} { # $win.df.desc insert 0.0 [text_wrap $ldata($aid,desc) 40] $win.df.desc insert 0.0 $ldata($aid,desc) } proc get_new_session_desc {} [format { %s.df.desc get 0.0 end-1c } $win ] } pack $win.descl -side top -anchor w pack $win.df.desc -side left -fill both -expand true pack $win.df.sb -side left -fill y pack $win.df -side top -fill both -expand true } proc new_mk_session_url {win aid} { global ldata if {[winfo exists $win.url]==0} { frame $win.url -borderwidth 2 -relief groove frame $win.url.f0 label $win.url.f0.l -text URL: entry $win.url.f0.e -width 30 -relief sunken -borderwidth 2 \ -bg [option get . entryBackground Sdr] \ -highlightthickness 0 tixAddBalloon $win.url.f0.e Entry [tt "You can enter a URL here to provide additional information about your session.\n\nA URL is a reference to a web page. E.g. http://www"] button $win.url.f0.b -text "Test URL" \ -highlightthickness 0 \ -command \ { $win.url.f0.e select from 0; \ $win.url.f0.e select to end; \ catch {selection get} url; \ timedmsgpopup "Testing URL - please wait" $url 5000; \ stuff_mosaic } tixAddBalloon $win.url.f0.b Button [tt "Click here to test the URL entered in the box to the left of this button"] if {[string compare $aid "new"]!=0} { if {$ldata($aid,uri)!=0} { $win.url.f0.e insert 0 $ldata($aid,uri) } } proc get_new_session_uri {} [format { %s.url.f0.e get } $win ] } pack $win.url -side top -fill x -expand true -ipady 2 -ipadx 2 -pady 2 pack $win.url.f0 -side top -fill x -expand true pack $win.url.f0.l -side left pack $win.url.f0.e -side left -fill x -expand true pack $win.url.f0.b -side left } proc new_mk_session_admin {win aid scope} { global zone send medialist ttl ldata #admin scope frame if {[winfo exists $win]==0} { frame $win -relief groove -borderwidth 2 label $win.l -text "Area Reached:" tixAddBalloon $win.l Label [tt "The area reached determines the \ range of the session. People outside this area will not be able to receive it."] frame $win.f text $win.f.lb -width 15 -height 6 -relief flat \ -relief sunken -borderwidth 1 -yscroll "$win.f.sb set" \ -highlightthickness 0 scrollbar $win.f.sb -borderwidth 1 -command "$win.f.lb yview" \ -highlightthickness 0 if {[string compare $aid "new"]!=0} { for {set mnum 0} {$mnum < $ldata($aid,medianum)} {incr mnum} { set send($ldata($aid,$mnum,media)) 1 } } for {set i 0} {$i < $zone(no_of_zones)} {incr i} { $win.f.lb insert [expr $i+1].0 "$zone(name,$i)" $win.f.lb tag add line$i [expr $i+1].0 end-1c $win.f.lb tag configure line$i -background\ [option get . background Sdr] $win.f.lb insert end " \n" $win.f.lb tag bind line$i <1> \ [format { set ttl $zone(ttl,%s) set addr [generate_address $zone(base_addr,%s) \ $zone(netmask,%s) %s] if {$addr!=0} { \ for {set i 0} {$i < $zone(no_of_zones)} {incr i} { %s.f.lb tag configure line$i -background\ [option get . background Sdr] } %s.f.lb tag configure line%s -background\ [option get . activeBackground Sdr] if {$addr!=1} { foreach media $medialist { if {$send($media)==1} { store_new_session_addr $media \ [generate_address $zone(base_addr,%s) \ $zone(netmask,%s)] } } } set zone(cur_zone) %s } } $i $i $i $aid $win $win $i $i $i $i] } if {($scope=="admin")&&([string compare $aid "new"]==0)} { set ttl $zone(ttl,0) } elseif {[string compare $aid "new"]!=0} { set ttl $ldata($aid,ttl) } else { set ttl 15 } $win.f.lb configure -state disabled $win.f.lb tag configure line$zone(cur_zone) -background\ [option get . activeBackground Sdr] } if {$scope=="admin"} {pack $win -side left -fill both -expand true} pack $win.l -side top -anchor w pack $win.f -side top -fill both -expand true pack $win.f.lb -side left -fill both -expand true pack $win.f.sb -side right -fill y -expand true } proc store_new_session_addr {media str} { global tmpdata #we need to set this before we retrieve it in new_mk_session_media set tmpdata($media) $str } proc retrieve_new_session_addr {media} { global tmpdata set res $tmpdata($media) unset tmpdata($media) return $res } proc new_mk_session_media {win aid scope show_details} { global ldata tmpdata zone medialist sd_menu send global media_fmt media_proto media_attr media_layers global mediaenc sessionkey #multicast address and ttl if {[winfo exists $win]==0} { frame $win -relief groove -borderwidth 2 #Media frame $win.l label $win.l.1 -text [tt "Media:"] -anchor w -width 15 label $win.l.5 -text [tt "Protocol"] -anchor w -width 8 label $win.l.2 -text [tt "Format"] -anchor w -width 9 label $win.l.3 -text [tt "Address"] -anchor w -width 13 label $win.l.6 -text [tt "Layers"] -anchor w -width 6 label $win.l.4 -text [tt "Port"] -anchor w -width 6 label $win.l.7 -text [tt "Encryption"] -anchor w -width 12 foreach attr [array names media_attr] { unset media_attr($attr) } if {[string compare $aid "new"]!=0} { for {set mnum 0} {$mnum < $ldata($aid,medianum)} {incr mnum} { set send($ldata($aid,$mnum,media)) 1 #set media_attr($ldata($aid,$mnum,media)) $ldata($aid,$mnum,vars) #puts "vars: $ldata($aid,$mnum,vars)" foreach var $ldata($aid,$mnum,vars) { set key [lindex [split $var ":"] 0] set value [lindex [split $var ":"] 1] if {$value==""} { set media_attr($ldata($aid,$mnum,media),$key) 1 } else { set media_attr($ldata($aid,$mnum,media),$key) $value } } } } foreach media $medialist { if {[string compare $aid "new"]!=0} { for {set mnum 0} {$mnum < $ldata($aid,medianum)} {incr mnum} { if {$ldata($aid,$mnum,media)==$media} { set localmnum $mnum if { $ldata($aid,$mnum,mediakey) != "" } { set mediaenc($media) 1 } else { set mediaenc($media) 0 } } } } else { # default to unencrypted media streams set mediaenc($media) 0 } frame $win.$media button $win.$media.cb -command "togglemedia $win $media" if {[is_creatable $media]==0} { $win.$media.cb configure -state disabled } iconbutton $win.$media.mb -text $media -bitmap [get_icon $media] -width 10 -relief raised\ -menu $win.$media.mb.menu create_menu $win.$media.mb.menu "" "" $media "create" menubutton $win.$media.fmt -width 8 -relief raised\ -menu $win.$media.fmt.menu create_fmt_menu $win $win.$media.fmt $win.$media.layers \ [lindex [get_media_protos $media] 0] \ [get_media_fmts $media [lindex [get_media_protos $media] 0]] $media menubutton $win.$media.proto -width 6 -relief raised\ -menu $win.$media.proto.menu create_proto_menu $win $win.$media.proto $win.$media.layers \ $win.$media.fmt [get_media_protos $media] $media entry $win.$media.addr -width 14 -relief sunken\ -bg [option get . entryBackground Sdr] \ -highlightthickness 0 menubutton $win.$media.layers -width 3 -relief raised\ -menu $win.$media.layers.menu create_layers_menu $win $win.$media.layers $media entry $win.$media.port -width 6 -relief sunken\ -bg [option get . entryBackground Sdr] \ -highlightthickness 0 checkbutton $win.$media.b1 -variable mediaenc($media) \ -highlightthickness 0 \ -command "toggleenc $media $win" tixAddBalloon $win.$media.b1 Button [tt "Click here to toggle the $media encryption on/off."] entry $win.$media.enc -width 25 -relief sunken \ -bg [option get . entryBackground Sdr] \ -highlightthickness 0 tixAddBalloon $win.$media.enc Entry [tt "The $media encryption key is shown here. You can replace the random key by typing your own key in this field."] #not all media are creatable #if we don't have the tools installed, don't let the #media be configured because we won't be able to join #our own session if {[is_creatable $media]==0} { setmediamode $media $win $send($media) 0 continue } set media_fmt($media) \ [lindex [get_media_fmts $media [lindex [get_media_protos $media] 0]] 0] set media_proto($media) [lindex [get_media_protos $media] 0] set media_layers($media) \ [get_max_layers $media $media_proto($media) $media_fmt($media)] if {([string compare $aid "new"]==0)&&($send($media)==1)} { if {$scope=="admin"} { $win.$media.addr insert 0 [generate_address $zone(base_addr,$zone(cur_zone)) $zone(netmask,$zone(cur_zone))] } else { $win.$media.addr insert 0 [generate_address] } setmediamode $media $win $send($media) 1 } elseif {([string compare $aid "new"]!=0)&&($send($media)==1)} { setmediaflags $media $win $aid setmediamode $media $win $send($media) 0 } else { setmediamode $media $win $send($media) 0 } if {$show_details==1} { if {[string compare $aid "new"]!=0} { if { $mediaenc($media) == 1} { $win.$media.enc configure -bg [option get . entryBackground Sdr] \ -state normal -relief sunken $win.$media.enc delete 0 end $win.$media.enc insert 0 $ldata($aid,$localmnum,mediakey) } else { $win.$media.enc delete 0 end $win.$media.enc configure -bg [option get . background Sdr] \ -relief groove -state disabled } } else { if { $mediaenc($media) == 1 } { $win.$media.enc configure -bg [option get . entryBackground Sdr] \ -state normal -relief sunken $win.$media.enc delete 0 end $win.$media.enc insert 0 $sessionkey($media) } else { $win.$media.enc delete 0 end $win.$media.enc configure -bg [option get . background Sdr] \ -relief groove -state disabled } } } else { if {[string compare $aid "new"]!=0} { if { $mediaenc($media) == 1} { set sessionkey($media) $ldata($aid,$localmnum,mediakey) } } } # end of media loop } proc get_new_session_addr {media} [format { if {$media=="conference"} { #XXX delete this when create no longer asks for it return 224.0.0.0 } else { %s.$media.addr get } } $win $win] proc get_new_session_port {media} [format { %s.$media.port get } $win ] proc get_new_session_proto {media} { } proc get_new_session_format {media} { } } foreach media $medialist { if {[info exists tmpdata($media)]} { $win.$media.addr delete 0 end $win.$media.addr insert 0 [retrieve_new_session_addr $media] } pack $win.$media -side top -anchor w -padx 10 -pady 2 pack $win.$media.cb -side left pack $win.$media.mb -side left -fill y if {$show_details==1} { pack $win.$media.proto -side left -fill y -padx 2 } pack $win.$media.fmt -side left -fill y -padx 2 if {$show_details==1} { pack $win.$media.addr -side left -padx 2 } pack $win.$media.layers -side left -padx 2 if {$show_details==1} { pack $win.$media.port -side left -padx 2 } if {$show_details==1} { pack $win.$media.b1 -side left } else { pack $win.$media.b1 -side left -padx 10m } if {$show_details==1} { pack $win.$media.enc -side left -padx 2 } } pack $win.l.1 -side left -anchor w if {$show_details==1} { pack $win.l.5 -side left -anchor w } pack $win.l.2 -side left -anchor w if {$show_details==1} { pack $win.l.3 -side left -anchor w } pack $win.l.6 -side left -anchor w if {$show_details==1} { pack $win.l.4 -side left -anchor w } pack $win.l.7 -side left -anchor w if {$show_details==1} { pack $win -fill x -side top -anchor w -pady 5 } else { pack $win -fill both -expand true -side top -anchor nw } } proc new_mk_session_time_box {win box maxbox rpt_times menu_disabled} { global ifstyle if {($box==1)&&($ifstyle(create)=="norm")} { label $win.expl -font [resource infoFont] -text \ "how often it takes place when it first takes place how long each time" pack $win.expl -side top } frame $win.fb$box set mb $win.fb$box.m menubutton $mb -width 20 -anchor w\ -relief raised -borderwidth 1 -menu $mb.m menu $mb.m -tearoff 0 pack $mb -side left -anchor w set ctr 0 foreach i $rpt_times { if {[lindex $menu_disabled $ctr]==0} { $mb.m add command -label $i -command "\ $mb configure -text \"$i\";\ set rpt_menu_value($box) $ctr;\ configure_rpt_menu $box $win.fb$box;\ configure_duration_box $win.fd $maxbox" } else { $mb.m add command -label $i -state disabled } incr ctr } pack $win.fb$box -side top pack [label $win.fb$box.l -text "from:"] -side left day_widget $win.fb$box.day now pack [label $win.fb$box.l1 -text "at"] -side left time_widget $win.fb$box.time now pack [label $win.fb$box.l2 -text "for"] -side left duration_widget $win.fb$box.duration 7200 pack [frame $win.pad$box -height 10] -side top configure_rpt_menu $box $win.fb$box } proc new_mk_session_contact {win aid} { global ldata yourname yourphone youremail if {[winfo exists $win]==0} { frame $win -relief groove -borderwidth 2 label $win.l -text "Person to contact about this session:" tixAddBalloon $win.l Label [tt "Name, email address and telephone \ number of person to be contacted about the session. You can \ edit the suggested address and telephone number. To edit the \ default, choose \"Preferences\" in the session main session \ window, then \"You\"."] frame $win.f0 label $win.f0.l -bitmap mail -anchor w entry $win.f0.e -width 35 -relief sunken \ -bg [option get . entryBackground Sdr] \ -highlightthickness 0 tixAddBalloon $win.f0.e Entry [tt "Enter your name and email address here"] frame $win.f1 label $win.f1.l -bitmap phone -anchor w entry $win.f1.e -width 35 -relief sunken \ -bg [option get . entryBackground Sdr] \ -highlightthickness 0 tixAddBalloon $win.f1.e Entry [tt "Enter your telephone number here"] if {[string compare $aid "new"]!=0} { foreach p $ldata($aid,phonelist) { $win.f1.e insert 0 $p } foreach e $ldata($aid,emaillist) { $win.f0.e insert 0 $e } } else { $win.f1.e insert 0 "$yourname $yourphone" $win.f0.e insert 0 "$yourname <$youremail>" } } pack $win.l -side top -anchor nw pack $win.f0 -side top -pady 3 pack $win.f0.l -side left -fill x -anchor s pack $win.f0.e -side bottom -anchor sw pack $win.f1 -side top pack $win.f1.l -side left -fill x pack $win.f1.e -side left -fill x -expand true pack $win -side top -fill both -expand true } #AUTH do_add creatation proc new_mk_session_buttons {win aid} { frame $win if {[string compare $aid "new"]!=0} { button $win.create -text [tt "Modify"] -command \ "if {\[create\]==1} \ { do_ad_creation $aid;\ destroy .new}" tixAddBalloon $win.create Button [tt "Click here to advertise the modified session. Changing the session name may result in some sites seeing duplicate announcements for a while."] } else { button $win.create -text [tt "Create"] -command \ "if {\[create\]==1} {destroy .new}" \ -highlightthickness 0 tixAddBalloon $win.create Button [tt "When you've filled out all the above information, click here to create and advertise this session"] } button $win.cal -text [tt "Show Daily Listings"] -command "calendar" \ -highlightthickness 0 tixAddBalloon $win.cal Button [tt "Click here to show a calendar of current sessions"] button $win.help -text [tt "Help"] -command "help" \ -highlightthickness 0 tixAddBalloon $win.help Button [tt "Click here for more help or to turn balloon help off"] button $win.dismiss -text "Dismiss" -command "destroy .new" \ -highlightthickness 0 tixAddBalloon $win.dismiss Button [tt "Click here to close this window"] pack $win.create -side left -fill x -expand true pack $win.cal -side left -fill x -expand true pack $win.help -side left -fill x -expand true pack $win.dismiss -side left -fill x -expand true pack $win -fill x } proc set_ttl_scope {win ttl} { case $ttl { 15 { $win.f3.rr.r1 invoke;return} 63 { $win.f3.rr.r2 invoke;return} 127 {$win.f3.rr.r3 invoke;return} default { # puts $ttl $win.f3.rr.f.r4 invoke } } } proc day_widget {widget time} { global $widget frame $widget if {$time!="now"} { set [set widget](startdayofweek) [lindex [gettime $time] 5] set [set widget](monthix) [fixint [lindex [gettime $time] 1]] set [set widget](dayofmonth) [fixint [lindex [gettime $time] 2]] } else { set [set widget](startdayofweek) [lindex [gettimenow] 5] set [set widget](monthix) [fixint [lindex [gettimenow] 1]] set [set widget](dayofmonth) [fixint [lindex [gettimenow] 2]] } set [set widget](dayix) 0 set [set widget](today_day) \ [getdayname [set [set widget](startdayofweek)]] set [set widget](today_mon) [getmonname [set [set widget](monthix)]] label $widget.bx -relief sunken -width 10 -text \ "[set [set widget](today_day)] [set [set widget](dayofmonth)] [set [set widget](today_mon)]" frame $widget.f button $widget.f.up -bitmap uparrow -relief flat \ -borderwidth 0 -command "changeday $widget 1" \ -highlightthickness 0 button $widget.f.down -bitmap downarrow -relief flat \ -borderwidth 0 -command "changeday $widget -1" \ -highlightthickness 0 pack $widget.f.up -side top pack $widget.f.down -side bottom pack $widget.f -side right pack $widget.bx -side right pack $widget -side left proc $widget.workaround {command args} [format { global %s case $command { configure { configure_day_widget %s [lindex $args 0] [lindex $args 1] } get { return [set %s(dayix)] } } } $widget $widget $widget $widget] } proc configure_day_widget {widget flag value} { global $widget case $flag { "-state" { case $value { disabled { $widget.f.up configure -state disabled $widget.f.down configure -state disabled $widget.bx configure \ -relief groove\ -fg [option get . background Sdr] } normal { $widget.f.up configure -state normal $widget.f.down configure -state normal $widget.bx configure \ -relief sunken\ -fg [option get . foreground Sdr] } } } "-time" { set [set widget](startdayofweek) [lindex [gettime $value] 5] set [set widget](monthix) [fixint [lindex [gettime $value] 1]] set [set widget](dayofmonth) [fixint [lindex [gettime $value] 2]] set [set widget](dayix) 0 set [set widget](today_day) \ [getdayname [set [set widget](startdayofweek)]] set [set widget](today_mon) [getmonname [set [set widget](monthix)]] $widget.bx configure -text \ "[set [set widget](today_day)] [set [set widget](dayofmonth)] [set [set widget](today_mon)]" } } } proc changeday {widget change} { global $widget daysinmonth if {($change < 0)&&([set [set widget](dayix)] >= [expr 0 - $change])} { set [set widget](dayix) [expr [set [set widget](dayix)] + $change] set [set widget](dayofmonth) [expr [set [set widget](dayofmonth)] + $change] } if {$change > 0} { set [set widget](dayix) [expr [set [set widget](dayix)] + $change] set [set widget](dayofmonth) [expr [set [set widget](dayofmonth)] + $change] } set thismonthlen [lindex $daysinmonth [expr [set [set widget](monthix)] - 1]] if {[set [set widget](dayofmonth)] > $thismonthlen} { set [set widget](dayofmonth) [expr [set [set widget](dayofmonth)] - $thismonthlen] incr [set widget](monthix) if {[set [set widget](monthix)]==13} {set [set widget](monthix) 1} } if {[set [set widget](dayofmonth)]==0} { incr [set widget](monthix) -1 if {[set [set widget](monthix)]==0} {set [set widget](monthix) 12} set thismonthlen [lindex $daysinmonth [expr [set [set widget](monthix)] - 1]] set [set widget](dayofmonth) $thismonthlen } set tmpday [expr ([set [set widget](dayix)] + [set [set widget](startdayofweek)]) % 7] $widget.bx configure -text \ "[getdayname $tmpday] [set [set widget](dayofmonth)] [getmonname [set [set widget](monthix)]]" } proc time_widget {widget time} { global $widget if {$time!="now"} { set [set widget](timeofday) $time } else { set [set widget](timeofday) [expr [format %d [expr [gettimeofday] / 1800]] * 1800] } frame $widget if {$time!="now"} { label $widget.bx -relief sunken -width 5 \ -text [timethen $widget $time] } else { label $widget.bx -relief sunken -width 5 -text [timenow $widget] } frame $widget.f button $widget.f.up -bitmap uparrow -relief flat -borderwidth 0 \ -command "$widget.bx configure -text \[changetime $widget 1\]" \ -highlightthickness 0 button $widget.f.down -bitmap downarrow -relief flat -borderwidth 0 -command "$widget.bx configure -text \[changetime $widget -1\]" \ -highlightthickness 0 pack $widget.f.up -side top pack $widget.f.down -side top pack $widget.f -side right pack $widget.bx -side right pack $widget -side left proc $widget.workaround {command args} [format { global %s case $command { configure { configure_time_widget %s [lindex $args 0] [lindex $args 1] } get { return [set %s(timeofday)] } } } $widget $widget $widget $widget] } proc configure_time_widget {widget flag value} { global $widget case $flag { "-state" { case $value { disabled { $widget.f.up configure -state disabled $widget.f.down configure -state disabled $widget.bx configure \ -relief groove\ -fg [option get . background Sdr] } normal { $widget.f.up configure -state normal $widget.f.down configure -state normal $widget.bx configure \ -relief sunken\ -fg [option get . foreground Sdr] } } } "-time" { set [set widget](timeofday) $value $widget.bx configure -text [timethen $widget $value] } } } proc changetime {widget change} { global $widget #we may have got given a hour with a leading zero - if so remove it #to avoid confusing TCL if {[string range [set [set widget](hrs)] 0 0] == "0"} { if {[string length [set [set widget](hrs)]] == 2} { set [set widget](hrs) [string range [set [set widget](hrs)] 1 1] } } if {$change == -1} { if {[set [set widget](mins)]==30} { set [set widget](mins) 0 if {[set [set widget](hrs)]<0} {set [set widget](hrs) 0;set [set widget](mins) 30} else { incr [set widget](timeofday) -1800 } } else { if {[set [set widget](hrs)]!=0} { set [set widget](mins) 30 incr [set widget](hrs) -1 incr [set widget](timeofday) -1800 } } } else { if {$change!=1} {puts "odd change value $change"} if {[set [set widget](mins)]==0} { set [set widget](mins) 30 incr [set widget](timeofday) 1800 } else { set [set widget](mins) 0 incr [set widget](hrs) 1 if {[set [set widget](hrs)] > 23} {set [set widget](hrs) 23; set [set widget](mins) 30} else { incr [set widget](timeofday) 1800 } } } if {[set [set widget](hrs)] < 10} { set hrsstr 0[set [set widget](hrs)] } else {set hrsstr [set [set widget](hrs)]} if {[set [set widget](mins)] < 10} { set minsstr 0[set [set widget](mins)] } else { set minsstr [set [set widget](mins)] } return $hrsstr:$minsstr } proc timenow {widget} { global $widget set [set widget](hrs) [lindex [gettimenow] 3] set [set widget](mins) [lindex [gettimenow] 4] if {[set [set widget](mins)] < 30} { set [set widget](mins) "00" } else { set [set widget](mins) 30 } return [set [set widget](hrs)]:[set [set widget](mins)] } proc timethen {widget t} { global $widget set [set widget](hrs) [lindex [gettime $t] 3] set [set widget](mins) [lindex [gettime $t] 4] return [set [set widget](hrs)]:[set [set widget](mins)] } proc duration_widget {widget duration} { global $widget set [set widget](durationix) [get_duration_ix_by_time $duration] #max time of 8 weeks set [set widget](duration_max) 4838400 set [set widget](duration_min) 0 if {$duration!=0} { frame $widget label $widget.bx -relief sunken -width 10 \ -text [get_duration [set [set widget](durationix)]] frame $widget.f button $widget.f.up -bitmap uparrow -relief flat -borderwidth 0 \ -highlightthickness 0 \ -command [format { incr %s(durationix) if {[set %s(durationix)] > 28} { set %s(durationix) 28 } if {[expr [get_realduration [set %s(durationix)]]*60] > [set %s(duration_max)]} { incr %s(durationix) -1 } %s.bx configure -text \ [get_duration [set %s(durationix)]] } $widget $widget $widget $widget $widget $widget $widget $widget] button $widget.f.down -bitmap downarrow -relief flat -borderwidth 0 \ -highlightthickness 0 \ -command [format {\ incr %s(durationix) -1; if {[set %s(durationix)] < 0} { set %s(durationix) 0 }; if {[expr [get_realduration [set %s(durationix)]]*60] < [set %s(duration_min)]} { incr %s(durationix) 1 } %s.bx configure -text \ [get_duration [set %s(durationix)]] } $widget $widget $widget $widget $widget $widget $widget $widget] pack $widget.f.up -side top pack $widget.f.down -side top pack $widget.bx -side left pack $widget.f -side left pack $widget -side top -fill x -padx 3 -pady 2 } else { label $widget -text [tt "Permanent Session"] pack $widget -side top -anchor ne set timeofday 0 set dayix 0 set [set widget](durationix) 0 } proc $widget.workaround {command args} [format { global %s case $command { configure { configure_duration_widget %s [lindex $args 0] [lindex $args \ 1] } set { #args 1 is time in minutes set tmp [lindex $args 0] catch {set tmp %s(duration_min)} if {$tmp > [lindex $args 0]} {return 0} set tmp [get_duration_ix_by_time [expr [lindex $args 0] * 60]] set %s(durationix) $tmp %s.bx configure -text \ [get_duration $tmp] } minval { #args 1 is time in minutes set %s(duration_min) [expr [lindex $args 0] * 60] } get { return [get_realduration [set %s(durationix)]] } } } $widget $widget $widget $widget $widget $widget $widget $widget] } proc configure_duration_widget {widget flag value} { global $widget case $flag { "-state" { case $value { disabled { $widget.f.up configure -state disabled $widget.f.down configure -state disabled $widget.bx configure \ -fg [option get . background Sdr]\ -relief groove } normal { $widget.f.up configure -state normal $widget.f.down configure -state normal $widget.bx configure \ -fg [option get . foreground Sdr]\ -relief sunken } } } "-time" { set [set widget](durationix) [get_duration_ix_by_time $value] $widget.bx configure -text [get_duration [set [set widget](durationix)]] } } } proc enter_phone_details {cmd} { global yourphone youremail yourname if {($yourname=="" || $youremail=="") && [file exists "~/.RTPdefaults"]} { option readfile "~/.RTPdefaults" if {$yourname==""} { set yourname [option get . rtpName Sdr] } if {$youremail==""} { set youremail [option get . rtpEmail Sdr] } } catch {destroy .phone} toplevel .phone wm title .phone "Sdr: Configure" frame .phone.f -borderwidth 2 -relief groove pack .phone.f -side top message .phone.f.l -text "Please configure sdr with your name, email address and phone number. These will be given as the defaults when you create a session, but you will still be able to override them for each session" pack .phone.f.l -side top frame .phone.f.f0 pack .phone.f.f0 -side top -fill x -expand true label .phone.f.f0.l -text "Name:" pack .phone.f.f0.l -side left -anchor e -fill x -expand true entry .phone.f.f0.e -width 40 -relief sunken -borderwidth 1 \ -bg [option get . entryBackground Sdr] \ -highlightthickness 0 if {$yourname!=""} { .phone.f.f0.e insert 0 $yourname } pack .phone.f.f0.e -side left frame .phone.f.f1 pack .phone.f.f1 -side top -fill x -expand true label .phone.f.f1.l -text "Email:" pack .phone.f.f1.l -side left -anchor e -fill x -expand true entry .phone.f.f1.e -width 40 -relief sunken -borderwidth 1 \ -bg [option get . entryBackground Sdr] \ -highlightthickness 0 if {$youremail!=""} { .phone.f.f1.e insert 0 $youremail } else { .phone.f.f1.e insert 0 "[getemailaddress]" } pack .phone.f.f1.e -side left frame .phone.f.f2 pack .phone.f.f2 -side top -fill x -expand true label .phone.f.f2.l -text "Phone:" pack .phone.f.f2.l -side left -anchor e -fill x -expand true entry .phone.f.f2.e -width 40 -relief sunken -borderwidth 1 \ -bg [option get . entryBackground Sdr] \ -highlightthickness 0 pack .phone.f.f2.e -side left frame .phone.f.f3 pack .phone.f.f3 -side top -fill x -expand true button .phone.f.f3.ok -text OK -command "\ set yourphone \[.phone.f.f2.e get\];\ set youremail \[.phone.f.f1.e get\];\ set yourname \[.phone.f.f0.e get\];\ if {\$yourname=={}} {\ errorpopup {Please enter your name} {Please enter your name};\ focus .phone.f.f0.e;\ } elseif {\$youremail=={}} {\ errorpopup {Please enter your email address} {Please enter your email address};\ focus .phone.f.f1.e;\ } elseif {\$yourphone=={}} {\ errorpopup {Please enter a phone number} {Please enter your telephone number};\ focus .phone.f.f2.e;\ }\ save_prefs; \ destroy .phone; \ eval $cmd \ " pack .phone.f.f3.ok -side left -fill x -expand true button .phone.f.f3.cancel -text Cancel \ -command {set wait_on_me 0;destroy .phone} pack .phone.f.f3.cancel -side left -fill x -expand true move_onscreen .phone } proc configure_rpt_menu {box win} { global has_times rpt_menu_value rpt_times duration_max global [set win].day global [set win].duration $win.m configure -text [lindex $rpt_times $rpt_menu_value($box)] if {[lindex $has_times $rpt_menu_value($box)] == 0} { foreach i {day.workaround time.workaround duration.workaround} { $win.$i configure -state disabled } foreach i {l l1 l2 } { $win.$i configure -fg [option get . disabledForeground Sdr] } } else { foreach i {day.workaround time.workaround duration.workaround} { $win.$i configure -state normal } foreach i {l l1 l2 } { $win.$i configure -fg [option get . foreground Sdr] } set [set win].duration(duration_max) [lindex $duration_max $rpt_menu_value($box)] } } proc configure_duration_box {win no_of_boxes} { global rpt_menu_value needs_lifetime rpt_min_values set flag 0 set duration 0 for {set i 1} {$i<=$no_of_boxes} {incr i} { set flag [expr $flag + [lindex $needs_lifetime $rpt_menu_value($i)]] if {[lindex $rpt_min_values $rpt_menu_value($i)]> $duration} { set duration [lindex $rpt_min_values $rpt_menu_value($i)] } } if {$flag==0} { $win.duration.workaround configure -state disabled $win.l configure -foreground [option get . disabledForeground Sdr] } else { $win.duration.workaround configure -state normal $win.duration.workaround set $duration $win.duration.workaround minval $duration $win.l configure -foreground [option get . foreground Sdr] } } proc get_expiry_time {basewin ix durationwin} { global rpt_menu_value needs_lifetime has_times set dayix [$basewin.day.workaround get] set timeofday [$basewin.time.workaround get] set duration [expr [$basewin.duration.workaround get]*60] set rval $rpt_menu_value($ix) set durationmod [expr [lindex $needs_lifetime $rval] * [$durationwin.workaround get] * 60] set starttime [expr [lindex $has_times $rval]*[unix_to_ntp [expr $timeofday+($dayix*86400)]]] set stoptime [expr [lindex $has_times $rval]*[expr $starttime + $duration + $durationmod]] case $rval { 0 { set rpt_str "0 0 0" } 1 { set rpt_str "0 $duration 0"} 2 { set rpt_str "86400 $duration 0"} 3 { set rpt_str "604800 $duration 0"} 4 { set rpt_str "1209600 $duration 0"} 5 { set rpt_str "0 0 0"} 6 { set rpt_str "604800 $duration 0 86400 172800 259200 345600"} } return "$starttime $stoptime $rpt_str" } proc create_menu {mname mlist defattrlist media mode} { global media_attr if {$mode=="create"} { menu $mname -tearoff 0 } else { #delete old menus if we're using this to modify a menu if {[$mname index end]!="none"} { for {set i 0} {$i <= [$mname index end]} {incr i} { # puts "$i [$mname index end]" catch {destroy [$mname entrycget $i -menu]} } $mname delete 0 end } } #parse the default attributes for this media/protocol/format foreach defattr $defattrlist { set tmpattr [lindex [split $defattr ":"] 0] set tmpvalue [lindex [split $defattr ":"] 1] catch {set tmpvalue $media_attr($media,$tmpattr)} set media_attr($media,$tmpattr) $tmpvalue } #parse the list of attributes this media had last time (empty string if new announcement) # foreach attr [array names media_attr] { # set tmpmedia [lindex [split $attr ','] 0] # set tmpattr [lindex [split $attr ','] 1] # if {$tmpmedia==$media} { # if {$tmpattr==""} { # set pitem($tmpattr) 1 # } else { # set pitem($tmpattr) $media_attr($attr) # } # } # } # set previtems [split $mediavars ','] # foreach previtem $previtems { # set pitemlist [split $previtem ':'] # if {[llength $pitemlist]==1} { # set pitem([lindex $pitemlist 0]) 1 # } else { # set pitem([lindex $pitemlist 0]) [lindex $pitemlist 1] # } # } #now create the menus with the above data # puts $mlist set mitems [split $mlist "\n"] foreach item $mitems { set itemlist [split $item ':'] set itemname [lindex $itemlist 0] set itemlist [lindex $itemlist 1] set code [catch {set media_attr($media,$itemname)}] if {$code==1} {set media_attr($media,$itemname) ""} if {[llength $itemlist]<=1} { $mname add checkbutton -label [get_attr_name $itemname] \ -variable media_attr\($media,$itemname\) \ -command "mtk_ImbUnpost {}" # set media_attr($media,$itemname) $pitem($itemname) } else { $mname add cascade -label [get_attr_name $itemname] \ -menu $mname.$itemname -command "mtk_ImbUnpost {}" menu $mname.$itemname -tearoff 0 foreach subitem $itemlist { $mname.$itemname add radiobutton \ -label [get_attrvalue_name $itemname $subitem] \ -variable media_attr\($media,$itemname\) \ -value $subitem -command "mtk_ImbUnpost {}" # set media_attr($media,$itemname) $pitem($itemname) } } } } proc create_fmt_menu {win mname layersmname proto fmtlist media} { menu $mname.menu -tearoff 0 foreach item $fmtlist { $mname.menu add radiobutton -label [get_fmt_name $item] \ -variable media_fmt\($media\) \ -value $item \ -command "reset_media_attrs;\ $mname configure -text \[get_fmt_name $item\];\ set_layers_menu $win $layersmname $media \ [get_max_layers $media $proto $item];\ setmediamode $media $win 1 0" } } proc set_fmt_menu {win mname layersmname proto fmtlist media} { global media_fmt $mname.menu delete 0 end foreach item $fmtlist { $mname.menu add radiobutton -label [get_fmt_name $item] \ -variable media_fmt\($media\) \ -value $item \ -command "reset_media_attrs;\ $mname configure -text \[get_fmt_name $item\];\ set_layers_menu $win $layersmname $media \ [get_max_layers $media $proto $item];\ setmediamode $media $win 1 0" } set media_fmt($media) [lindex $fmtlist 0] } proc create_proto_menu {win mname layersmname fmtmname fmtlist media} { menu $mname.menu -tearoff 0 foreach item $fmtlist { $mname.menu add radiobutton -label [get_proto_name $item] \ -variable media_proto\($media\) \ -value $item \ -command "reset_media_attrs;\ $mname configure -text \[get_proto_name $item\];\ set_fmt_menu $win $layersmname $item $fmtmname \ \[get_media_fmts $media $item\] $media;\ setmediamode $media $win 1 0" } } proc create_layers_menu {win mname media} { menu $mname.menu -tearoff 0 foreach item {1 2 3 4} { $mname.menu add radiobutton -label $item \ -variable media_layers\($media\) \ -value $item \ -command "$mname configure -text $item" } } proc set_layers_menu {win mname media layers} { global media_layers $mname.menu delete 0 end for {set item 1} {$item <= $layers} {incr item} { $mname.menu add radiobutton -label $item \ -variable media_layers\($media\) \ -value $item \ -command "$mname configure -text $item" } $mname configure -text $layers set media_layers($media) $layers } proc reset_media_attrs {} { global media_attr foreach attr [array names media_attr] { unset media_attr($attr) } } #proc paste_buffer {w} { # set ipos [$w index insert] # $w insert $ipos [selection get] # set str [$w get 1.0 end] # $w delete 1.0 end # $w insert 1.0 [text_wrap $str 40] #} proc togglemedia {win media} { global send if {$send($media) == 0} { setmediamode $media $win 1 1 } else { setmediamode $media $win 0 1 } } proc toggleenc { media win } { global mediaenc sessionkey tempkey ifstyle # win is: SAP(norm)=.new.f3.media; SAP(tech)=.new.f1;SAP QCall=.qc.f.media if { $mediaenc($media) == 0} { # switch encryption off for media set sessionkey($media) "" if {$ifstyle(create)=="tech" && [string compare [string range $win 1 2] "qc"] != 0 } { $win.$media.enc delete 0 end $win.$media.enc configure -bg [option get . background Sdr] \ -relief groove -state disabled } } else { # switch encryption on for media make_random_key set sessionkey($media) $tempkey if {$ifstyle(create)=="tech" && [string compare [string range $win 1 2] "qc"] != 0 } { $win.$media.enc configure -bg [option get . entryBackground Sdr] \ -state normal -relief sunken $win.$media.enc delete 0 end $win.$media.enc insert 0 $sessionkey($media) } } } proc get_new_media_key {media} { global ifstyle sessionkey if {$ifstyle(create)=="tech"} { set win .new.f.f.media set sessionkey($media) [$win.$media.enc get] } return $sessionkey($media) } ############# #setmediamode is used to set a line of media widgets to active or inactive # #$media is typically "audio", "video", "whiteboard" or "text" #$state is 0 (media is inactive) or 1 (media is active) #$mediabase is the base of the media frame. ############# proc setmediamode {media mediabase state realloc} { global send media_fmt media_proto media_attr media_layers global zone scope defattrlist global mediaenc sessionkey tempkey set base $mediabase.$media set send($media) $state if {$state==0} { $base.cb configure -bitmap cross -foreground red $base.fmt configure -text " " -state disabled -relief groove #I thought -state disabled would do this but no.... bind $base.fmt { break } $base.proto configure -text " " -state disabled -relief groove bind $base.proto { break } $base.addr delete 0 end $base.addr configure -bg [option get . background Sdr] \ -relief groove -state disabled $base.enc delete 0 end $base.enc configure -text "" -bg [option get . background Sdr] \ -relief groove -state disabled $base.b1 configure -state disabled set mediaenc($media) 0 $base.layers configure -text " " -state disabled -relief groove $base.port delete 0 end $base.port configure -bg [option get . background Sdr] \ -relief groove -state disabled $base.mb.workaround configure -relief groove -state disabled if {[is_creatable $media]==1} { set media_fmt($media) [lindex [get_media_fmts $media $media_proto($media)] 0] set media_proto($media) [lindex [get_media_protos $media] 0] } } else { if {[string compare $media_proto($media) ""]==0} { msgpopup "No tool installed" "You have no tool installed that could participate in a session with this media" set send($media) 0 return 0 } $base.cb configure -bitmap tick -foreground green4 $base.fmt configure -text [get_fmt_name $media_fmt($media)] -state normal \ -relief raised bind $base.fmt "tkMbButtonUp $base.fmt" $base.proto configure -text [get_proto_name $media_proto($media)] \ -state normal -relief raised bind $base.proto "tkMbButtonUp $base.proto" if {$media_layers($media)==1} { $base.layers configure -text $media_layers($media) \ -state disabled -relief groove } else { $base.layers configure -text $media_layers($media) \ -state normal -relief raised } $base.addr configure -bg [option get . entryBackground Sdr] \ -state normal -relief sunken $base.port configure -bg [option get . entryBackground Sdr] \ -relief sunken -state normal # set encryption to off state if not just changing formats etc # but enable the encryption button to be used if {$realloc == 1} { $base.enc delete 0 end $base.enc configure -text "" -bg [option get . background Sdr] \ -relief groove -state disabled $base.b1 configure -state normal set mediaenc($media) 0 } if {$realloc==1} { $base.addr delete 0 end if {$scope=="admin"} { $base.addr insert 0 [generate_address $zone(base_addr,$zone(cur_zone)) $zone(netmask,$zone(cur_zone))] } else { $base.addr insert 0 [generate_address] } $base.port delete 0 end $base.port insert 0 [generate_port $media] } set attrlist "[get_proto_attrs $media $media_proto($media)] [get_fmt_attrs $media $media_proto($media) $media_fmt($media)]" # puts $attrlist set attrlist [fix_up_attr_list $attrlist] # puts "fmt: $media_fmt($media)" create_menu $base.mb.menu $attrlist $defattrlist($media.$media_proto($media).$media_fmt($media)) $media change $base.mb.workaround configure -relief raised -state normal } } proc fix_up_attr_list {origattrlist} { #takes an attrlist in the form "attr1:value attr1:value2 attr2:value3" #and forms an attrlist in the form "attr1:value1 value2\nattr2:value3" #this is needed because we merge protocol and format attrs and they #may have the same attributes set mainattrs {} foreach attr $origattrlist { set key [lindex [split $attr ":"] 0] set value [lindex [split $attr ":"] 1] if {[lsearch $mainattrs $key]==-1} { set mainattrs "$mainattrs $key" set values($key) \{$value\} } else { if {[lsearch $values($key) $value]==-1} { set values($key) "$values($key) \{$value\}" } } } set newattrlist "" foreach key $mainattrs { if {$newattrlist==""} { set newattrlist $key } else { set newattrlist "$newattrlist\n$key" } if {$values($key)!=""} { set newattrlist "$newattrlist:$values($key)" } } return $newattrlist } proc setmediaflags {media win aid} { global ldata tmpdata media_fmt media_proto media_layers set base $win.$media for {set mnum 0} {$mnum<$ldata($aid,medianum)} {incr mnum} { if {$ldata($aid,$mnum,media)==$media} { $base.proto configure -text \ [get_proto_name $ldata($aid,$mnum,proto)] set media_proto($media) $ldata($aid,$mnum,proto) $base.fmt configure -text [get_fmt_name $ldata($aid,$mnum,fmt)] set media_fmt($media) $ldata($aid,$mnum,fmt) set media_layers($media) $ldata($aid,$mnum,layers) $base.port delete 0 end $base.port insert 0 $ldata($aid,$mnum,port) $base.addr delete 0 end if {[info exists tmpdata($media)]} { $base.addr insert 0 [retrieve_new_session_addr $media] } else { $base.addr insert 0 $ldata($aid,$mnum,addr) } return 0 } } } proc generate_address {args} { global zone if {[llength $args]==0} { return [ui_generate_address] } elseif {[llength $args]==2} { return [eval "ui_generate_address $args"] } elseif {([llength $args]==3)||([llength $args]==1)} { if {([llength $args]==3)} { set baseaddr [lindex $args 0] set netmask [lindex $args 1] set aid [lindex $args 2] } else { set z $zone(ttl_scope) set baseaddr $zone(base_addr,$z) set netmask $zone(netmask,$z) set aid [lindex $args 0] } if {[string compare $aid "new"]==0} { return [ui_generate_address $baseaddr $netmask] } else { #we check if we really need to generate a new address or #if the old one is still OK... global ldata set pa [split $ldata($aid,tmpmulticast) "."] #it's simpler to subtract 224 from the msb than fix Tcl's #concept of what's positive and what's negative... set paddr [expr ((((((([lindex $pa 0]-224)*256)\ +[lindex $pa 1])*256)\ +[lindex $pa 2])*256)\ +[lindex $pa 3])] set ba [split $baseaddr "."] set baddr [expr ((((((([lindex $ba 0]-224)*256)\ +[lindex $ba 1])*256)\ +[lindex $ba 2])*256)\ +[lindex $ba 3])] set paddr [expr $paddr >> (32-$netmask)] set baddr [expr $baddr >> (32-$netmask)] if {$paddr==$baddr} { #we don't really need to generate a new address in #these circumstances, so don't do so (avoid confusion). return 1 } else { #should really warn the user when we have to do this toplevel .warn wm title .warn "Sdr: [tt "Warning"]" frame .warn.f -borderwidth 2 -relief groove pack .warn.f -side top -fill both message .warn.f.msg -aspect 400 -text \ [tt "To make this scope change I need to allocate new multicast addresses.\n\nThis means that anyone who is already using this annoucement will need to restart their applications\n\nIs this OK?"] pack .warn.f.msg -side top -fill x -expand true frame .warn.f.f -borderwidth 0 pack .warn.f.f -side top -fill x -expand true button .warn.f.ok -text [tt "OK"] -command \ "set ldata($aid,tmpmulticast2) \ \[ui_generate_address $baseaddr $netmask\];\ destroy .warn" pack .warn.f.ok -side left -fill x -expand true button .warn.f.cancel -text [tt "Cancel"] -command \ "set ldata($aid,tmpmulticast2) 0; destroy .warn" pack .warn.f.cancel -side left -fill x -expand true tkwait visibility .warn grab set .warn tkwait window .warn if {$ldata($aid,tmpmulticast2)==0} { unset ldata($aid,tmpmulticast2) return 0 } else { set ldata($aid,tmpmulticast) $ldata($aid,tmpmulticast2) unset ldata($aid,tmpmulticast2) return $ldata($aid,tmpmulticast) } } } } } proc generate_port {media} { ui_generate_port $media } #sdr.tcl #Copyright University College London 1995 #see ui_fns.c for information on usage and redistribution of this file #and for a DISCLAIMER OF ALL WARRANTIES. proc start_all {aid} { global ldata set success 1 for {set i 0} {$i < $ldata($aid,medianum)} {incr i} { set success [expr [start_media "$aid" $i "start"]&&$success] } # if {$success} { # timedmsgpopup [tt "Please wait..."] [tt "the conference tools are starting"] 3000 # } set ldata($aid,is_popped) -1; popdown $aid } proc start_media {aid mnum mode} { global sd_sess ldata # puts "aid: $aid" # puts "mnum: $mnum" set ldata($aid,started) 1 set media $ldata($aid,$mnum,media) set sd_sess(sess_id) $aid set sd_sess(address) $ldata($aid,multicast) set sd_sess(ttl) $ldata($aid,ttl) set sd_sess(name) $ldata($aid,session); set sd_sess(media) "" for {set i 0} {$i < $ldata($aid,medianum)} {incr i} { set sd_sess(media) "$sd_sess(media) $ldata($aid,$i,media)" } set sd_sess(creator) $ldata($aid,creator) set sd_sess(creator_id) $ldata($aid,source) set sd_sess(source_id) $ldata($aid,heardfrom) set sd_sess(arrival_time) $ldata($aid,theard) set sd_sess(start_time) $ldata($aid,starttime) set sd_sess(end_time) $ldata($aid,endtime) set sd_sess(attributes) "" global sd_$media set tmp sd_$media\(attributes\) set $tmp $ldata($aid,$mnum,vars) set tmp sd_$media\(mediakey\) if {[info exists ldata($aid,$mnum,mediakey)]} { set $tmp $ldata($aid,$mnum,mediakey) } else { set $tmp "" } set tmp sd_$media\(port\) set $tmp $ldata($aid,$mnum,port) set tmp sd_$media\(address\) set $tmp $ldata($aid,$mnum,addr) set tmp sd_$media\(layers\) set $tmp $ldata($aid,$mnum,layers) set tmp sd_$media\(ttl\) set $tmp $ldata($aid,$mnum,ttl) set tmp sd_$media\(proto\) set $tmp $ldata($aid,$mnum,proto) set tmp sd_$media\(fmt\) set $tmp $ldata($aid,$mnum,fmt) set tmp sd_$media\(proto\) set $tmp $ldata($aid,$mnum,proto) set sd_priv($media) 1 if {$mode=="start"} { if {[is_known_media $media]!=-1} { return [start_media_tool $aid $media $ldata($aid,$mnum,proto) $ldata($aid,$mnum,fmt) [split $ldata($aid,$mnum,vars) "\n"]] } else { msgpopup "Media $media unknown" "The session you tried to join contains a media \"$media\" that I do not know about. To join this session you need the \"$media\" sdr plug-in module and a media tool capable of joining this session. \n\nSee \"Help\" for more details of plug-in modules." return 0 } } elseif {$mode=="record"} { return [record_$media] } else { puts "unknown mode to start_media: $mode" return 0 } } #get_channel taken from sd.tcl by Van Jacobson set ipc_chan 0 proc get_channel { confid } { global ipc_tab ipc_chan if { [info exists ipc_tab($confid)] } { return $ipc_tab($confid) } incr ipc_chan if { $ipc_chan > 300 } { set ipc_chan 1 } set ipc_tab($confid) $ipc_chan return $ipc_chan } set applist " vat rat swplayer vic nv wb wbd nte" set medialist "audio video whiteboard text" set rules " audio.RTP/AVP.0 audio.RTP/AVP.5 audio.RTP/AVP.3 audio.RTP/AVP.7 audio.RTP/AVP.6 audio.RTP/AVP.8 audio.RTP/AVP.109 audio.RTP/AVP.111 audio.RTP/AVP.112 audio.RTP/AVP.113 audio.RTP/AVP.114 audio.RTP/AVP.115 audio.RTP/AVP.116 audio.RTP/AVP.117 audio.RTP/AVP.121 audio.RTP/AVP.122 audio.RTP/AVP.*(DYNAMIC) audio.rtp.pcm audio.rtp.pcm2 audio.rtp.pcm4 audio.rtp.dvi audio.rtp.dvi2 audio.rtp.dvi4 audio.rtp.gsm audio.rtp.lpc audio.rtp.lpc4 audio.vat.pcm audio.vat.pcm2 audio.vat.pcm4 audio.vat.dvi audio.vat.dvi2 audio.vat.dvi4 audio.vat.gsm audio.vat.lpc4 audio.Xing.MPEG video.RTP/AVP.31 video.RTP/AVP.28 video.RTP/AVP.26 video.RTP/AVP.25 video.RTP/AVP.120 video.RTP/AVP.*(DYNAMIC) video.rtp.h261 video.rtp.nv video.rtp.jpeg video.rtp.celb video.rtp.vic video.rtp.ivs whiteboard.udp.wb text.udp.nt" set createrules " audio.RTP/AVP.0 audio.RTP/AVP.5 audio.RTP/AVP.3 audio.RTP/AVP.7 audio.RTP/AVP.6 audio.RTP/AVP.8 audio.RTP/AVP.109 audio.RTP/AVP.111 audio.RTP/AVP.112 audio.RTP/AVP.113 audio.RTP/AVP.114 audio.RTP/AVP.115 audio.RTP/AVP.116 audio.RTP/AVP.117 audio.RTP/AVP.121 audio.RTP/AVP.122 audio.RTP/AVP.*(DYNAMIC) audio.vat.pcm audio.vat.pcm2 audio.vat.pcm4 audio.vat.dvi audio.vat.dvi2 audio.vat.dvi4 audio.vat.gsm audio.vat.lpc4 video.RTP/AVP.31 video.RTP/AVP.28 video.RTP/AVP.26 video.RTP/AVP.25 video.RTP/AVP.120 video.RTP/AVP.*(DYNAMIC) whiteboard.udp.wb text.udp.nt" set tooldata(cryptflag:vic) "-K" set tooldata(cryptflag:nte) "-k" set tooldata(cryptflag:rat) "-K" set tooldata(cryptflag:vat) "-K" set tooldata(cryptflag:wb) "-K" set mediadata(text:text) "Text" set mediadata(icon:text) "text" set mediadata(text:whiteboard) "Whiteboard" set mediadata(icon:whiteboard) "wb" set mediadata(text:audio) "Audio" set mediadata(icon:audio) "audio" set mediadata(text:video) "Video" set mediadata(icon:video) "eye" set fmts(audio.vat.gsm) "gsm" set fmts(audio.RTP/AVP.114) "114" set fmts(audio.RTP/AVP.115) "115" set fmts(audio.RTP/AVP.*(DYNAMIC)) "" set fmts(audio.RTP/AVP.116) "116" set fmts(audio.RTP/AVP.0) "0" set fmts(audio.vat.pcm2) "pcm2" set fmts(audio.RTP/AVP.117) "117" set fmts(audio.vat.lpc4) "lpc4" set fmts(audio.vat.dvi) "dvi" set fmts(audio.vat.pcm4) "pcm4" set fmts(audio.RTP/AVP.3) "3" set fmts(video.RTP/AVP.25) "25" set fmts(audio.vat.dvi2) "dvi2" set fmts(audio.RTP/AVP.121) "121" set fmts(video.RTP/AVP.26) "26" set fmts(audio.RTP/AVP.122) "122" set fmts(audio.RTP/AVP.5) "5" set fmts(audio.vat.dvi4) "dvi4" set fmts(audio.RTP/AVP.6) "6" set fmts(video.RTP/AVP.28) "28" set fmts(audio.vat.pcm) "pcm" set fmts(audio.RTP/AVP.7) "7" set fmts(video.RTP/AVP.120) "120" set fmts(audio.RTP/AVP.8) "8" set fmts(video.RTP/AVP.31) "31" set fmts(text.udp.nt) "nt" set fmts(audio.RTP/AVP.109) "109" set fmts(audio.RTP/AVP.111) "111" set fmts(audio.RTP/AVP.112) "112" set fmts(whiteboard.udp.wb) "wb" set fmts(video.RTP/AVP.*(DYNAMIC)) "" set fmts(audio.RTP/AVP.113) "113" set protos(audio.vat.gsm) "vat" set protos(audio.RTP/AVP.114) "RTP/AVP" set protos(audio.RTP/AVP.115) "RTP/AVP" set protos(audio.RTP/AVP.*(DYNAMIC)) "RTP/AVP" set protos(audio.RTP/AVP.116) "RTP/AVP" set protos(audio.RTP/AVP.0) "RTP/AVP" set protos(audio.vat.pcm2) "vat" set protos(audio.RTP/AVP.117) "RTP/AVP" set protos(audio.vat.lpc4) "vat" set protos(audio.vat.dvi) "vat" set protos(audio.vat.pcm4) "vat" set protos(audio.RTP/AVP.3) "RTP/AVP" set protos(video.RTP/AVP.25) "RTP/AVP" set protos(audio.vat.dvi2) "vat" set protos(audio.RTP/AVP.121) "RTP/AVP" set protos(video.RTP/AVP.26) "RTP/AVP" set protos(audio.RTP/AVP.122) "RTP/AVP" set protos(audio.RTP/AVP.5) "RTP/AVP" set protos(audio.vat.dvi4) "vat" set protos(audio.RTP/AVP.6) "RTP/AVP" set protos(video.RTP/AVP.28) "RTP/AVP" set protos(audio.vat.pcm) "vat" set protos(audio.RTP/AVP.7) "RTP/AVP" set protos(video.RTP/AVP.120) "RTP/AVP" set protos(audio.RTP/AVP.8) "RTP/AVP" set protos(video.RTP/AVP.31) "RTP/AVP" set protos(text.udp.nt) "udp" set protos(audio.RTP/AVP.109) "RTP/AVP" set protos(audio.RTP/AVP.111) "RTP/AVP" set protos(audio.RTP/AVP.112) "RTP/AVP" set protos(whiteboard.udp.wb) "udp" set protos(video.RTP/AVP.*(DYNAMIC)) "RTP/AVP" set protos(audio.RTP/AVP.113) "RTP/AVP" set protonames(RTP/AVP) "RTP" set protonames(udp) "udp" set protonames(Xing) "Xing" set protonames(rtp) "rtp" set protonames(vat) "vat" set fmtnames() "*(DYNAMIC)" set fmtnames(116) "16bit linear 48kHz mono" set fmtnames(0) "PCM u-law 8kHz mono" set fmtnames(wb) "wb" set fmtnames(h261) "h261" set fmtnames(117) "16bit linear 48kHz stereo" set fmtnames(nt) "UCL NTE" set fmtnames(ivs) "ivs" set fmtnames(120) "PVH" set fmtnames(dvi) "dvi" set fmtnames(3) "GSM 8kHz mono" set fmtnames(nv) "nv" set fmtnames(121) "Redundancy (8kHz)" set fmtnames(122) "16bit linear 8kHz mono" set fmtnames(5) "DVI 8kHz mono" set fmtnames(6) "DVI 16kHz mono" set fmtnames(25) "Cell B" set fmtnames(7) "LPC 8kHz mono" set fmtnames(26) "M-JPEG" set fmtnames(pcm) "pcm" set fmtnames(8) "PCM a-law 8kHz mono" set fmtnames(MPEG) "MPEG" set fmtnames(vic) "vic" set fmtnames(28) "nv" set fmtnames(pcm2) "pcm2" set fmtnames(109) "WB-ADPCM" set fmtnames(lpc4) "lpc4" set fmtnames(111) "16bit linear 8kHz stereo" set fmtnames(31) "H.261" set fmtnames(pcm4) "pcm4" set fmtnames(112) "16bit linear 16kHz mono" set fmtnames(dvi2) "dvi2" set fmtnames(113) "16bit linear 16kHz stereo" set fmtnames(celb) "celb" set fmtnames(jpeg) "jpeg" set fmtnames(114) "16bit linear 32kHz mono" set fmtnames(lpc) "lpc" set fmtnames(gsm) "gsm" set fmtnames(dvi4) "dvi4" set fmtnames(115) "16bit linear 32kHz stereo" set mappings(video.rtp.h261) "{vic -f h261 -t $(TTL) -I $(CHAN) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set mappings(audio.rtp.lpc) "{vat -r -f $(FMT) -I $(CHAN) -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set mappings(audio.vat.dvi2) "{vat $(CRYPTKEY) -I $(CHAN) -t $(TTL) -C $(SESSNAME) -f $(FMT) $(ADDRESS)/$(PORT)$(ID)}" set mappings(audio.vat.dvi4) "{vat $(CRYPTKEY) -I $(CHAN) -t $(TTL) -C $(SESSNAME) -f $(FMT) $(ADDRESS)/$(PORT)$(ID)}" set mappings(text.udp.nt) "{nte $(CRYPTKEY) -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set mappings(audio.RTP/AVP.109) "{rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(audio.RTP/AVP.111) "{rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(audio.RTP/AVP.112) "{rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(audio.RTP/AVP.113) "{rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(audio.rtp.lpc4) "{rat -f lpc -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set mappings(audio.RTP/AVP.114) "{rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(audio.vat.gsm) "{vat $(CRYPTKEY) -I $(CHAN) -t $(TTL) -C $(SESSNAME) -f $(FMT) $(ADDRESS)/$(PORT)$(ID)}" set mappings(audio.RTP/AVP.115) "{rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(audio.RTP/AVP.116) "{rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(audio.RTP/AVP.117) "{rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(audio.rtp.gsm) "{vat -r -f $(FMT) -I $(CHAN) -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)} {rat -f gsm -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set mappings(audio.vat.pcm2) "{vat $(CRYPTKEY) -I $(CHAN) -t $(TTL) -C $(SESSNAME) -f $(FMT) $(ADDRESS)/$(PORT)$(ID)}" set mappings(video.rtp.vic) "{vic -f h261 -t $(TTL) -I $(CHAN) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set mappings(audio.vat.pcm4) "{vat $(CRYPTKEY) -I $(CHAN) -t $(TTL) -C $(SESSNAME) -f $(FMT) $(ADDRESS)/$(PORT)$(ID)}" set mappings(audio.RTP/AVP.121) "{rat -pt 121/redundancy $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(audio.RTP/AVP.122) "{rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(audio.vat.pcm) "{vat $(CRYPTKEY) -I $(CHAN) -t $(TTL) -C $(SESSNAME) -f $(FMT) $(ADDRESS)/$(PORT)$(ID)}" set mappings(video.RTP/AVP.120) "{vic $(CRYPTKEY) -t $(TTL) -I $(CHAN) -C $(SESSNAME) $(ADDRESS)/$(PORT)$(DOLAYERS)}" set mappings(audio.rtp.pcm) "{vat -r -f $(FMT) -I $(CHAN) -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)} {rat -f pcm -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set mappings(whiteboard.udp.wb) "{wb $(CRYPTKEY) -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)} {wbd -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set mappings(audio.rtp.dvi2) "{vat -r -f $(FMT) -I $(CHAN) -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)} {rat -f dvi -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set mappings(audio.RTP/AVP.*(DYNAMIC)) "{rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(audio.rtp.dvi4) "{vat -r -f $(FMT) -I $(CHAN) -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)} {rat -f dvi -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set mappings(video.RTP/AVP.25) "{vic $(CRYPTKEY) -t $(TTL) -I $(CHAN) -C $(SESSNAME) $(ADDRESS)/$(PORT)$(DOLAYERS)}" set mappings(video.RTP/AVP.26) "{vic $(CRYPTKEY) -t $(TTL) -I $(CHAN) -C $(SESSNAME) $(ADDRESS)/$(PORT)$(DOLAYERS)}" set mappings(video.RTP/AVP.28) "{vic $(CRYPTKEY) -t $(TTL) -I $(CHAN) -C $(SESSNAME) $(ADDRESS)/$(PORT)$(DOLAYERS)}" set mappings(video.RTP/AVP.31) "{vic $(CRYPTKEY) -t $(TTL) -I $(CHAN) -C $(SESSNAME) $(ADDRESS)/$(PORT)$(DOLAYERS)}" set mappings(audio.Xing.MPEG) "{swplayer xdma://$(ADDRESS):$(PORT)/}" set mappings(audio.rtp.pcm2) "{vat -r -f $(FMT) -I $(CHAN) -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)} {rat -f pcm -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set mappings(video.rtp.jpeg) "{vic -f jpeg -t $(TTL) -I $(CHAN) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set mappings(audio.rtp.pcm4) "{vat -r -f $(FMT) -I $(CHAN) -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)} {rat -f pcm -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set mappings(audio.RTP/AVP.0) "{vat $(CRYPTKEY) -r -I $(CHAN) -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)} {rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(audio.vat.dvi) "{vat $(CRYPTKEY) -I $(CHAN) -t $(TTL) -C $(SESSNAME) -f $(FMT) $(ADDRESS)/$(PORT)$(ID)}" set mappings(audio.vat.lpc4) "{vat $(CRYPTKEY) -I $(CHAN) -t $(TTL) -C $(SESSNAME) -f $(FMT) $(ADDRESS)/$(PORT)$(ID)}" set mappings(audio.RTP/AVP.3) "{vat -f gsm $(CRYPTKEY) -r -I $(CHAN) -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)} {rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(video.rtp.nv) "{vic -f nv -Anv -t $(TTL) -I $(CHAN) -C $(SESSNAME) $(ADDRESS)/$(PORT)} {nv -ttl $(TTL) -title $(SESSNAME) $(ADDRESS) $(PORT)}" set mappings(audio.RTP/AVP.5) "{vat $(CRYPTKEY) -r -I $(CHAN) -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)} {rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(audio.rtp.dvi) "{vat -r -f $(FMT) -I $(CHAN) -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)} {rat -f dvi -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set mappings(audio.RTP/AVP.6) "{rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(audio.RTP/AVP.7) "{vat -f lpc $(CRYPTKEY) -r -I $(CHAN) -t $(TTL) -C $(SESSNAME) $(ADDRESS)/$(PORT)} {rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(audio.RTP/AVP.8) "{rat $(CRYPTKEY) -C $(SESSNAME) -t $(TTL) -f $(PRIMARY)$(SECONDARY) $(FMTP) $(ADDRESS)/$(PORT)}" set mappings(video.rtp.ivs) "{vic -f h261 -Aivs -t $(TTL) -I $(CHAN) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set mappings(video.RTP/AVP.*(DYNAMIC)) "{vic $(CRYPTKEY) -t $(TTL) -I $(CHAN) -C $(SESSNAME) $(ADDRESS)/$(PORT)$(DOLAYERS)}" set mappings(video.rtp.celb) "{vic -f celb -t $(TTL) -I $(CHAN) -C $(SESSNAME) $(ADDRESS)/$(PORT)}" set attrs(whiteboard.udp) "" set attrs(video.rtp.h261) "" set attrs(audio.rtp.lpc) "" set attrs(audio.rtp) "recvonly" set attrs(audio.vat.dvi2) "" set attrs(audio.Xing) "" set attrs(audio.vat.dvi4) "" set attrs(video.RTP/AVP) "" set attrs(video.rtp) "" set attrs(text.udp.nt) "" set attrs(text.udp) "" set attrs(audio.RTP/AVP.109) "{rtpmap:109\ WBS/16000/1} ptime:20 ptime:40 ptime:80 ptime:160" set attrs(audio.RTP/AVP.111) "{rtpmap:111\ L16/8000/2} ptime:20 ptime:40 ptime:80 ptime:160" set attrs(audio.RTP/AVP.112) "{rtpmap:112\ L16/16000/1} ptime:20 ptime:40 ptime:80 ptime:160" set attrs(audio.RTP/AVP.113) "{rtpmap:113\ L16/16000/2} ptime:20 ptime:40 ptime:80 ptime:160" set attrs(audio.rtp.lpc4) "" set attrs(audio.RTP/AVP.114) "{rtpmap:114\ L16/32000/1} ptime:20 ptime:40 ptime:80 ptime:160" set attrs(audio.vat.gsm) "" set attrs(audio.RTP/AVP.115) "{rtpmap:115\ L16/32000/2} ptime:20 ptime:40 ptime:80 ptime:160" set attrs(audio.RTP/AVP.116) "{rtpmap:116\ L16/48000/1} ptime:20 ptime:40 ptime:80 ptime:160" set attrs(video.rtp.vic) "" set attrs(audio.RTP/AVP.117) "{rtpmap:117\ L16/48000/2} ptime:20 ptime:40 ptime:80 ptime:160" set attrs(audio.rtp.gsm) "" set attrs(audio.vat.pcm2) "" set attrs(audio.vat.pcm4) "" set attrs(audio.RTP/AVP.121) "{rtpmap:121\ red/8000} rtpred1:0 rtpred1:5 rtpred2:5 rtpred2:7 ptime:20 ptime:40 ptime:80 ptime:160" set attrs(audio.RTP/AVP.122) "{rtpmap:122\ L16/8000/1} ptime:20 ptime:40 ptime:80 ptime:160" set attrs(audio.vat.pcm) "" set attrs(video.RTP/AVP.120) "{rtpmap:120\ PVH/90000}" set attrs(audio.rtp.pcm) "" set attrs(whiteboard.udp.wb) "orient:portrait orient:landscape orient:seascape sendrecv orient:portrait orient:landscape orient:seascape sendrecv" set attrs(audio.rtp.dvi2) "" set attrs(audio.RTP/AVP.*(DYNAMIC)) "rtpmap rtpmap rtpmap rtpmap rtpmap rtpmap rtpmap rtpmap rtpmap rtpmap rtpmap rtpmap rtpmap {rtpmap:$(DYNAMIC)\ red/8000} {rtpmap:$(DYNAMIC)\ red/16000} {rtpmap:$(DYNAMIC)\ red/32000} {rtpmap:$(DYNAMIC)\ red/48000} {rtpmap:$(DYNAMIC)\ WBS/16000/1} {rtpmap:$(DYNAMIC)\ L16/8000/1} {rtpmap:$(DYNAMIC)\ L16/8000/2} {rtpmap:$(DYNAMIC)\ L16/16000/1} {rtpmap:$(DYNAMIC)\ L16/16000/2} {rtpmap:$(DYNAMIC)\ L16/32000/1} {rtpmap:$(DYNAMIC)\ L16/32000/2} {rtpmap:$(DYNAMIC)\ L16/48000/1} {rtpmap:$(DYNAMIC)\ L16/48000/2} rtpred1 rtpred2" set attrs(audio.rtp.dvi4) "" set attrs(audio.vat) "id recvonly" set attrs(audio.RTP/AVP) "recvonly" set attrs(video.RTP/AVP.25) "" set attrs(video.RTP/AVP.26) "" set attrs(video.RTP/AVP.28) "" set attrs(video.RTP/AVP.31) "" set attrs(audio.Xing.MPEG) "" set attrs(audio.rtp.pcm2) "" set attrs(video.rtp.jpeg) "" set attrs(audio.rtp.pcm4) "" set attrs(audio.RTP/AVP.0) "ptime:20 ptime:40 ptime:80 ptime:20 ptime:40 ptime:80 ptime:160" set attrs(audio.vat.dvi) "" set attrs(audio.vat.lpc4) "" set attrs(video.rtp.nv) "" set attrs(audio.RTP/AVP.3) "ptime:20 ptime:40 ptime:80 ptime:160" set attrs(audio.RTP/AVP.5) "ptime:20 ptime:40 ptime:80 ptime:20 ptime:40 ptime:80 ptime:160" set attrs(audio.rtp.dvi) "" set attrs(audio.RTP/AVP.6) "ptime:20 ptime:40 ptime:80 ptime:160" set attrs(audio.RTP/AVP.7) "ptime:20 ptime:40 ptime:80 ptime:160" set attrs(audio.RTP/AVP.8) "ptime:20 ptime:40 ptime:80 ptime:160" set attrs(video.rtp.ivs) "" set attrs(video.rtp.celb) "" set attrs(video.RTP/AVP.*(DYNAMIC)) "rtpmap {rtpmap:$(DYNAMIC)\ PVH/90000}" set attrnames(orient) "Orientation" set attrnames(id) "Channel Id" set attrnames(sendrecv) "Send/Receive Mode" set attrnames(rtpred1) "Primary Encoding" set attrnames(recvonly) "Receive-Only Mode" set attrnames(rtpred2) "Redundant Encoding" set attrnames(ptime) "Packetisation interval" set attrvaluenames(orient:seascape) "Upside-down Landscape" set attrvaluenames(orient:portrait) "Portrait" set attrvaluenames(rtpred2:7) "LPC-8k-MONO" set attrvaluenames(rtpred1:0) "PCMU-8k-MONO" set attrvaluenames(ptime:160) "160ms" set attrvaluenames(rtpred1:5) "DVI-8k-MONO" set attrvaluenames(ptime:80) "80ms" set attrvaluenames(ptime:40) "40ms" set attrvaluenames(orient:landscape) "Landscape" set attrvaluenames(rtpred2:5) "DVI-8k-MONO" set attrvaluenames(ptime:20) "20ms" set attrflags(rat.audio.RTP/AVP.*(DYNAMIC).rtpmap:$(DYNAMIC)\ L16/48000/2) "-pt $(DYNAMIC)/L16/48000/2" set attrflags(vat.audio.RTP/AVP.5.ptime:20) "-f dvi" set attrflags(wbd.whiteboard.udp.wb.sendrecv) "+r" set attrflags(wb.whiteboard.udp.wb.orient:landscape) "-l" set attrflags(rat.audio.RTP/AVP.*(DYNAMIC).rtpmap:$(DYNAMIC)\ L16/8000/1) "-pt $(DYNAMIC)/L16/8000/1" set attrflags(vat.audio.RTP/AVP.5.ptime:40) "-f dvi2" set attrflags(rat.audio.RTP/AVP.*(DYNAMIC).rtpmap:$(DYNAMIC)\ red/8000) "-pt $(DYNAMIC)/redundancy" set attrflags(vat.audio.vat.recvonly) "-R" set attrflags(rat.audio.RTP/AVP.*(DYNAMIC).rtpmap:$(DYNAMIC)\ L16/8000/2) "-pt $(DYNAMIC)/L16/8000/2" set attrflags(vat.audio.RTP/AVP.0.ptime:20) "-f pcm" set attrflags(wb.whiteboard.udp.wb.sendrecv) "+r" set attrflags(vat.audio.RTP/AVP.0.ptime:40) "-f pcm2" set attrflags(vat.audio.RTP/AVP.5.ptime:80) "-f dvi4" set attrflags(wbd.whiteboard.udp.wb.orient:seascape) "+l" set attrflags(wbd.whiteboard.udp.wb.orient:portrait) "-p" set attrflags(rat.audio.RTP/AVP.*(DYNAMIC).rtpmap:$(DYNAMIC)\ L16/32000/1) "-pt $(DYNAMIC)/L16/32000/1" set attrflags(rat.audio.RTP/AVP.*(DYNAMIC).rtpmap:$(DYNAMIC)\ red/32000) "-pt $(DYNAMIC)/redundancy" set attrflags(rat.audio.RTP/AVP.*(DYNAMIC).rtpmap:$(DYNAMIC)\ L16/32000/2) "-pt $(DYNAMIC)/L16/32000/2" set attrflags(rat.audio.RTP/AVP.*(DYNAMIC).rtpmap:$(DYNAMIC)\ L16/16000/1) "-pt $(DYNAMIC)/L16/16000/1" set attrflags(vat.audio.RTP/AVP.0.ptime:80) "-f pcm4" set attrflags(rat.audio.RTP/AVP.*(DYNAMIC).rtpmap:$(DYNAMIC)\ red/16000) "-pt $(DYNAMIC)/redundancy" set attrflags(rat.audio.RTP/AVP.*(DYNAMIC).rtpmap:$(DYNAMIC)\ L16/16000/2) "-pt $(DYNAMIC)/L16/16000/2" set attrflags(rat.audio.RTP/AVP.*(DYNAMIC).rtpmap:$(DYNAMIC)\ WBS/16000/1) "-pt $(DYNAMIC)/WBS/16000/1" set attrflags(wb.whiteboard.udp.wb.orient:seascape) "+l" set attrflags(wb.whiteboard.udp.wb.orient:portrait) "-p" set attrflags(vat.audio.RTP/AVP.recvonly) "-R" set attrflags(wbd.whiteboard.udp.wb.orient:landscape) "-l" set attrflags(vat.audio.rtp.recvonly) "-R" set attrflags(rat.audio.RTP/AVP.*(DYNAMIC).rtpmap:$(DYNAMIC)\ L16/48000/1) "-pt $(DYNAMIC)/L16/48000/1" set attrflags(rat.audio.RTP/AVP.*(DYNAMIC).rtpmap:$(DYNAMIC)\ red/48000) "-pt $(DYNAMIC)/redundancy" set noattrflags(vat.audio.RTP/AVP.0.ptime) "-f pcm2" set noattrflags(vat.audio.RTP/AVP.5.ptime) "-f dvi2" set noattrflags(wbd.whiteboard.udp.wb.sendrecv) "+r" set noattrflags(wb.whiteboard.udp.wb.sendrecv) "+r" set noattrlist(rat.audio.RTP/AVP) "" set noattrlist(vic.video.RTP/AVP.120) "" set noattrlist(rat.audio.rtp) "" set noattrlist(vat.audio.RTP/AVP) "" set noattrlist(vat.audio.rtp) "" set noattrlist(rat.audio.RTP/AVP.109) "" set noattrlist(wbd.whiteboard.udp.wb) " recvonly" set noattrlist(rat.audio.RTP/AVP.111) "" set noattrlist(vat.audio.rtp.dvi2) "" set noattrlist(rat.audio.RTP/AVP.112) "" set noattrlist(rat.audio.RTP/AVP.113) "" set noattrlist(vat.audio.rtp.dvi4) "" set noattrlist(rat.audio.RTP/AVP.114) "" set noattrlist(vic.video.RTP/AVP.25) "" set noattrlist(rat.audio.RTP/AVP.115) "" set noattrlist(vic.video.RTP/AVP.26) "" set noattrlist(rat.audio.RTP/AVP.116) "" set noattrlist(rat.audio.RTP/AVP.117) "" set noattrlist(vic.video.RTP/AVP.28) "" set noattrlist(vic.video.RTP/AVP.31) "" set noattrlist(rat.audio.RTP/AVP.121) "" set noattrlist(rat.audio.RTP/AVP.122) "" set noattrlist(rat.audio.rtp.dvi) "" set noattrlist(rat.audio.rtp.lpc4) "" set noattrlist(vat.audio.vat.dvi) "" set noattrlist(wb.whiteboard.udp) "" set noattrlist(nv.video.rtp.nv) "" set noattrlist(vic.video.rtp.jpeg) "" set noattrlist(vat.audio.rtp.pcm2) "" set noattrlist(vat.audio.rtp.dvi) "" set noattrlist(vat.audio.rtp.pcm4) "" set noattrlist(vic.video.rtp.nv) "" set noattrlist(vat.audio.vat.lpc4) "" set noattrlist(wb.whiteboard.udp.wb) " recvonly" set noattrlist(rat.audio.RTP/AVP.0) "" set noattrlist(rat.audio.RTP/AVP.3) "" set noattrlist(wbd.whiteboard.udp) "" set noattrlist(vic.video.rtp.ivs) "" set noattrlist(vat.audio.RTP/AVP.0) " ptime" set noattrlist(rat.audio.RTP/AVP.5) "" set noattrlist(vat.audio.rtp.lpc) "" set noattrlist(vat.audio.vat) "" set noattrlist(rat.audio.RTP/AVP.6) "" set noattrlist(rat.audio.RTP/AVP.7) "" set noattrlist(vat.audio.RTP/AVP.3) "" set noattrlist(rat.audio.rtp.dvi2) "" set noattrlist(vic.video.rtp.celb) "" set noattrlist(vic.video.RTP/AVP.*(DYNAMIC)) "" set noattrlist(rat.audio.RTP/AVP.8) "" set noattrlist(vat.audio.RTP/AVP.5) " ptime" set noattrlist(rat.audio.rtp.dvi4) "" set noattrlist(vic.video.rtp.h261) "" set noattrlist(swplayer.audio.Xing.MPEG) "" set noattrlist(vat.audio.RTP/AVP.7) "" set noattrlist(vat.audio.vat.dvi2) "" set noattrlist(rat.audio.rtp.gsm) "" set noattrlist(nte.text.udp.nt) "" set noattrlist(vic.video.RTP/AVP) "" set noattrlist(vat.audio.vat.gsm) "" set noattrlist(vat.audio.vat.dvi4) "" set noattrlist(vic.video.rtp) "" set noattrlist(rat.audio.rtp.pcm2) "" set noattrlist(vat.audio.rtp.gsm) "" set noattrlist(rat.audio.rtp.pcm4) "" set noattrlist(rat.audio.RTP/AVP.*(DYNAMIC)) "" set noattrlist(nte.text.udp) "" set noattrlist(rat.audio.rtp.pcm) "" set noattrlist(vat.audio.vat.pcm) "" set noattrlist(vic.video.rtp.vic) "" set noattrlist(swplayer.audio.Xing) "" set noattrlist(vat.audio.vat.pcm2) "" set noattrlist(nv.video.rtp) "" set noattrlist(vat.audio.rtp.pcm) "" set noattrlist(vat.audio.vat.pcm4) "" set defattrlist(whiteboard.udp) "" set defattrlist(video.rtp.h261) "" set defattrlist(audio.rtp.lpc) "" set defattrlist(audio.rtp) "" set defattrlist(audio.vat.dvi2) "" set defattrlist(audio.Xing) "" set defattrlist(audio.vat.dvi4) "" set defattrlist(video.RTP/AVP) "" set defattrlist(video.rtp) "" set defattrlist(text.udp.nt) "" set defattrlist(text.udp) "" set defattrlist(audio.RTP/AVP.109) "{rtpmap:109\ WBS/16000/1} ptime:40" set defattrlist(audio.RTP/AVP.111) "{rtpmap:111\ L16/8000/2} ptime:40" set defattrlist(audio.RTP/AVP.112) "{rtpmap:112\ L16/16000/1} ptime:40" set defattrlist(audio.RTP/AVP.113) "{rtpmap:113\ L16/16000/2} ptime:40" set defattrlist(audio.rtp.lpc4) "" set defattrlist(audio.RTP/AVP.114) "{rtpmap:114\ L16/32000/1} ptime:40" set defattrlist(audio.vat.gsm) "" set defattrlist(audio.RTP/AVP.115) "{rtpmap:115\ L16/32000/2} ptime:40" set defattrlist(audio.RTP/AVP.116) "{rtpmap:116\ L16/48000/1} ptime:40" set defattrlist(video.rtp.vic) "" set defattrlist(audio.RTP/AVP.117) "{rtpmap:117\ L16/48000/2} ptime:40" set defattrlist(audio.rtp.gsm) "" set defattrlist(audio.vat.pcm2) "" set defattrlist(audio.vat.pcm4) "" set defattrlist(audio.RTP/AVP.121) "{rtpmap:121\ red/8000} rtpred1:5 rtpred2:5 ptime:40" set defattrlist(audio.RTP/AVP.122) "{rtpmap:122\ L16/8000/1} ptime:40" set defattrlist(audio.vat.pcm) "" set defattrlist(video.RTP/AVP.120) "{rtpmap:120\ PVH/90000}" set defattrlist(audio.rtp.pcm) "" set defattrlist(whiteboard.udp.wb) "" set defattrlist(audio.rtp.dvi2) "" set defattrlist(audio.RTP/AVP.*(DYNAMIC)) "" set defattrlist(audio.rtp.dvi4) "" set defattrlist(audio.vat) "" set defattrlist(audio.RTP/AVP) "" set defattrlist(video.RTP/AVP.25) "" set defattrlist(video.RTP/AVP.26) "" set defattrlist(video.RTP/AVP.28) "" set defattrlist(video.RTP/AVP.31) "" set defattrlist(audio.Xing.MPEG) "" set defattrlist(audio.rtp.pcm2) "" set defattrlist(video.rtp.jpeg) "" set defattrlist(audio.rtp.pcm4) "" set defattrlist(audio.RTP/AVP.0) "ptime:40" set defattrlist(audio.vat.dvi) "" set defattrlist(audio.vat.lpc4) "" set defattrlist(video.rtp.nv) "" set defattrlist(audio.RTP/AVP.3) "ptime:40" set defattrlist(audio.RTP/AVP.5) "ptime:40" set defattrlist(audio.rtp.dvi) "" set defattrlist(audio.RTP/AVP.6) "ptime:40" set defattrlist(audio.RTP/AVP.7) "ptime:40" set defattrlist(audio.RTP/AVP.8) "ptime:40" set defattrlist(video.rtp.ivs) "" set defattrlist(video.rtp.celb) "" set defattrlist(video.RTP/AVP.*(DYNAMIC)) "" set withattrs(audio.RTP/AVP.*(DYNAMIC)) "{rtpmap:$(DYNAMIC) red/8000} {rtpmap:$(DYNAMIC) red/16000} {rtpmap:$(DYNAMIC) red/32000} {rtpmap:$(DYNAMIC) red/48000} {rtpmap:$(DYNAMIC) WBS/16000/1} {rtpmap:$(DYNAMIC) L16/8000/1} {rtpmap:$(DYNAMIC) L16/8000/2} {rtpmap:$(DYNAMIC) L16/16000/1} {rtpmap:$(DYNAMIC) L16/16000/2} {rtpmap:$(DYNAMIC) L16/32000/1} {rtpmap:$(DYNAMIC) L16/32000/2} {rtpmap:$(DYNAMIC) L16/48000/1} {rtpmap:$(DYNAMIC) L16/48000/2}" set withattrs(video.RTP/AVP.*(DYNAMIC)) "{rtpmap:$(DYNAMIC) PVH/90000}" set macros(vic.video.RTP/AVP.28) "/nv/$(TTL)" set macros(rat.audio.RTP/AVP.116.rtpmap) "l16-48k-mono" set macros(vic.video.RTP/AVP.120) "/pvh/$(TTL)/$(LAYERS)" set macros(rat.audio.RTP/AVP.3) "gsm" set macros(vic.video.RTP/AVP.31) "/h261/$(TTL)" set macros(rat.audio.RTP/AVP.121.rtpred1) "dvi" set macros(rat.audio.RTP/AVP.121.rtpred2) "/lpc" set macros(rat.audio.RTP/AVP.5) "dvi" set macros(rat.audio.RTP/AVP.111.rtpmap) "l16-8k-stereo" set macros(rat.audio.RTP/AVP.6) "dvi-16k-mono" set macros(rat.audio.RTP/AVP.7) "lpc" set macros(rat.audio.RTP/AVP.113.rtpmap) "l16-16k-stereo" set macros(vat.audio.vat.id) "/$(VALUE)" set macros(rat.audio.RTP/AVP.*(DYNAMIC).rtpred1) "$(VALUE)" set macros(rat.audio.RTP/AVP.8) "pcma-8k-mono" set macros(rat.audio.RTP/AVP.*(DYNAMIC).rtpred2) "/$(VALUE)" set macros(rat.audio.RTP/AVP.115.rtpmap) "l16-32k-stereo" set macros(vic.video.RTP/AVP.*(DYNAMIC).rtpmap) "/pvh/$(TTL)/$(LAYERS)" set macros(rat.audio.RTP/AVP.*(DYNAMIC).rtpmap) "$(DYNAMIC)" set macros(rat.audio.RTP/AVP.117.rtpmap) "l16-48k-stereo" set macros(rat.audio.RTP/AVP.109.rtpmap) "wbs-16k-mono" set macros(rat.audio.RTP/AVP.112.rtpmap) "l16-16k-mono" set macros(vic.video.RTP/AVP.25) "/celb/$(TTL)" set macros(rat.audio.RTP/AVP.122.rtpmap) "l16" set macros(vic.video.RTP/AVP.26) "/jpeg/$(TTL)" set macros(rat.audio.RTP/AVP.0) "pcm" set macros(rat.audio.RTP/AVP.114.rtpmap) "l16-32k-mono" set macrokeys(vic.video.RTP/AVP.28) "DOLAYERS" set macrokeys(rat.audio.RTP/AVP.116.rtpmap) "PRIMARY" set macrokeys(vic.video.RTP/AVP.120) "DOLAYERS" set macrokeys(rat.audio.RTP/AVP.3) "PRIMARY" set macrokeys(vic.video.RTP/AVP.31) "DOLAYERS" set macrokeys(rat.audio.RTP/AVP.121.rtpred1) "PRIMARY" set macrokeys(rat.audio.RTP/AVP.121.rtpred2) "SECONDARY" set macrokeys(rat.audio.RTP/AVP.5) "PRIMARY" set macrokeys(rat.audio.RTP/AVP.111.rtpmap) "PRIMARY" set macrokeys(rat.audio.RTP/AVP.6) "PRIMARY" set macrokeys(rat.audio.RTP/AVP.7) "PRIMARY" set macrokeys(rat.audio.RTP/AVP.113.rtpmap) "PRIMARY" set macrokeys(vat.audio.vat.id) "ID" set macrokeys(rat.audio.RTP/AVP.*(DYNAMIC).rtpred1) "PRIMARY" set macrokeys(rat.audio.RTP/AVP.8) "PRIMARY" set macrokeys(rat.audio.RTP/AVP.*(DYNAMIC).rtpred2) "SECONDARY" set macrokeys(rat.audio.RTP/AVP.115.rtpmap) "PRIMARY" set macrokeys(vic.video.RTP/AVP.*(DYNAMIC).rtpmap) "DOLAYERS" set macrokeys(rat.audio.RTP/AVP.*(DYNAMIC).rtpmap) "PRIMARY" set macrokeys(rat.audio.RTP/AVP.117.rtpmap) "PRIMARY" set macrokeys(rat.audio.RTP/AVP.109.rtpmap) "PRIMARY" set macrokeys(rat.audio.RTP/AVP.112.rtpmap) "PRIMARY" set macrokeys(vic.video.RTP/AVP.25) "DOLAYERS" set macrokeys(rat.audio.RTP/AVP.122.rtpmap) "PRIMARY" set macrokeys(vic.video.RTP/AVP.26) "DOLAYERS" set macrokeys(rat.audio.RTP/AVP.0) "PRIMARY" set macrokeys(rat.audio.RTP/AVP.114.rtpmap) "PRIMARY" set fmtlayers(video.rtp.h261) "1" set fmtlayers(audio.rtp.lpc) "1" set fmtlayers(audio.vat.dvi2) "1" set fmtlayers(audio.vat.dvi4) "1" set fmtlayers(text.udp.nt) "1" set fmtlayers(audio.RTP/AVP.109) "1" set fmtlayers(audio.RTP/AVP.111) "1" set fmtlayers(audio.RTP/AVP.112) "1" set fmtlayers(audio.RTP/AVP.113) "1" set fmtlayers(audio.rtp.lpc4) "1" set fmtlayers(audio.RTP/AVP.114) "1" set fmtlayers(audio.vat.gsm) "1" set fmtlayers(audio.RTP/AVP.115) "1" set fmtlayers(audio.RTP/AVP.116) "1" set fmtlayers(audio.RTP/AVP.117) "1" set fmtlayers(audio.rtp.gsm) "1" set fmtlayers(audio.vat.pcm2) "1" set fmtlayers(video.rtp.vic) "1" set fmtlayers(audio.vat.pcm4) "1" set fmtlayers(audio.RTP/AVP.121) "1" set fmtlayers(audio.RTP/AVP.122) "1" set fmtlayers(audio.vat.pcm) "1" set fmtlayers(video.RTP/AVP.120) "4" set fmtlayers(audio.rtp.pcm) "1" set fmtlayers(whiteboard.udp.wb) "1" set fmtlayers(audio.rtp.dvi2) "1" set fmtlayers(audio.RTP/AVP.*(DYNAMIC)) "1" set fmtlayers(audio.rtp.dvi4) "1" set fmtlayers(video.RTP/AVP.25) "1" set fmtlayers(video.RTP/AVP.26) "1" set fmtlayers(video.RTP/AVP.28) "1" set fmtlayers(video.RTP/AVP.31) "1" set fmtlayers(audio.Xing.MPEG) "1" set fmtlayers(audio.rtp.pcm2) "1" set fmtlayers(video.rtp.jpeg) "1" set fmtlayers(audio.rtp.pcm4) "1" set fmtlayers(audio.RTP/AVP.0) "1" set fmtlayers(audio.vat.dvi) "1" set fmtlayers(audio.vat.lpc4) "1" set fmtlayers(audio.RTP/AVP.3) "1" set fmtlayers(video.rtp.nv) "1" set fmtlayers(audio.RTP/AVP.5) "1" set fmtlayers(audio.rtp.dvi) "1" set fmtlayers(audio.RTP/AVP.6) "1" set fmtlayers(audio.RTP/AVP.7) "1" set fmtlayers(audio.RTP/AVP.8) "1" set fmtlayers(video.rtp.ivs) "1" set fmtlayers(video.RTP/AVP.*(DYNAMIC)) "1" set fmtlayers(video.rtp.celb) "1" set tmp {} catch {set tmp $applist} set applist $tmp set tmp {} catch {set tmp $rules} set rules $tmp set tmp {} catch {set tmp $medialist} set medialist $tmp set tmp {} catch {set tmp $createrules} set createrules $tmp proc parse_plugins {plugindir needtool} { global rules mappings createrules global fmts fmtnames protos protonames set pluginfiles [lsort [glob -nocomplain $plugindir/sdr2.plugin.*]] foreach filename $pluginfiles { # puts "opening $filename..." set file [vopen $filename "r"] parse_plugin $file $needtool vclose $file # puts "...closing $filename" } } #implement a virtual file so we can push input back onto stdin to do macro #expansion proc vopen {filename mode} { global ibufs set file [open $filename $mode] set ibufs($file) "" return $file } proc vclose {file} { global ibufs close $file unset ibufs($file) } proc vgets {file varname} { global ibufs if {$ibufs($file)!=""} { set val [lindex [split $ibufs($file) "\n"] 0] set ibufs($file) \ [join [lrange [split $ibufs($file) "\n"] 1 end] "\n"] uplevel set $varname \"$val\" return 0 } else { return [uplevel gets $file $varname] } } proc vpush {file string} { global ibufs set ibufs($file) "$string$ibufs($file)" } proc parse_plugin {file needtool} { global applist global mappings global rules global createrules global fmts fmtnames protos protonames global attrs attrnames attrvaluenames attrflags noattrflags noattrlist global defattrlist withattrs fmtlayers global medialist macros macrokeys set fmtlist {} set stack {} set currulectr 0 set currules {} set create yes while {[eof $file]==0} { if {[vgets $file line]==-1} { break } set line [string trim $line] #ignore comments if {[string index $line 0]=="\#"} { continue } set tag [string trim [lindex [split $line ":"] 0]] set value [string trim [join [lrange [split $line ":"] 1 end] ":"]] switch $tag { "@define" { set varname [string trim $value] if {[vgets $file line]==-1} { break } if {[string trim $line]!="\{"} { puts "parse error in definition of macro $varname" return -1 } set stacked 1 set macrodef "" while {$stacked > 0} { if {[vgets $file line]==-1} { puts "end of file in definition of macro $varname" return -1 } if {[string trim $line]=="\{"} { incr stacked } if {[string trim $line]=="\}"} { incr stacked -1 } if {$stacked>0} { set macrodef "$macrodef\n$line" } } set macrodef "$macrodef\n" # puts "macro definition of $varname:\n$macrodef" set macrodefs($varname) $macrodef } "@expand" { set varname [string trim $value] vpush $file $macrodefs($varname) continue } media { set media [string trim $value] add_to_known_media $media } icon { add_media_icon $media [string trim $value] } text { add_media_text $media $value } cryptflag { add_tool_cryptflag $tool [string trim $value] } proto { set proto [string trim $value] set protoname $value set tmp {} catch {set tmp $attrs($media.$proto)} set attrs($media.$proto) $tmp set tmp {} catch {set tmp $defattrlist($media.$proto)} set defattrlist($media.$proto) $tmp set tmp {} catch {set tmp $noattrlist($tool.$media.$proto)} catch {set noattrlist($tool.$media.$proto) $tmp} } protoname { set protoname $value } tool { set tool [string trim $value] if {[lsearch $applist $tool]==-1} { # puts "tool $tool needs approval" set toolloc [find_tool $tool] if {($toolloc=="")&&($needtool=="yes")} { # puts "tool $tool is not installed" return 0 } else { # puts "tool $tool is installed as $toolloc" set applist "$applist $tool" } } set tmp {} catch {set tmp $noattrlist($tool.$media.$proto)} catch {set noattrlist($tool.$media.$proto) $tmp} } layers { if {[info exists fmtlayers($media.$proto.$curfmt)]} { if {$fmtlayers($media.$proto.$curfmt)< $value} { set fmtlayers($media.$proto.$curfmt) $value } } else { set fmtlayers($media.$proto.$curfmt) $value } } fmt { set curfmt [string trim $value " "] if {[info exists fmtlayers($media.$proto.$curfmt)]==0} { set fmtlayers($media.$proto.$curfmt) 1 } set tmpfmts($media.$proto.$curfmt) $value set tmpfmtnames($media.$proto.$curfmt) $value set tmp {} catch {set tmp $attrs($media.$proto.$curfmt)} set attrs($media.$proto.$curfmt) $tmp set tmp {} catch {set tmp $defattrlist($media.$proto.$curfmt)} set defattrlist($media.$proto.$curfmt) $tmp set noattrlist($tool.$media.$proto.$curfmt) {} set last fmt incr currulectr if {$currulectr==1} { set currules "$media.$proto.$curfmt" set curexec($media.$proto.$curfmt) "$tool" } else { set currules "$currules $media.$proto.$curfmt" set curexec($media.$proto.$curfmt) "$tool" } } "{" { set stack "$last $stack" } "}" { set stack [lrange $stack 1 end] } fmtname { if {[lindex $stack 0]=="fmt"} { set tmpfmtnames($media.$proto.$curfmt) $value } else { catch { puts "parse error: fmtname with no current format" } } } flags { if {[lindex $stack 0]=="fmt"} { set curexec($media.$proto.$curfmt) \ "$curexec($media.$proto.$curfmt) $value" } elseif {[lindex $stack 0]=="attr"} { if {[lindex $stack 1]=="fmt"} { set attrflags($tool.$media.$proto.$curfmt.$curattr) $value } else { set attrflags($tool.$media.$proto.$curattr) $value } } elseif {[lindex $stack 0]=="noattr"} { if {[lindex $stack 1]=="fmt"} { set noattrflags($tool.$media.$proto.$curfmt.$curattr) $value } else { set noattrflags($tool.$media.$proto.$curattr) $value } } elseif {[lindex $stack 0]=="attrvalue"} { if {[lindex $stack 2]=="fmt"} { # puts "$tool.$media.$proto.$curfmt.$curattr:$curattrvalue -> $value" set attrflags($tool.$media.$proto.$curfmt.$curattr:$curattrvalue) $value } else { set attrflags($tool.$media.$proto.$curattr:$curattrvalue) $value } } else { foreach currule $currules { set curexec($currule) "$curexec($currule) $value" } } } attr { set last attr set curattr [string trim $value] # puts "curattr: $curattr" if {[lindex $stack 0]=="fmt"} { #it's a format attribute lappend attrs($media.$proto.$curfmt) $curattr } else { #it's a protocol attribute lappend attrs($media.$proto) $curattr } } #specifies a compulsory attribute if a wildcard format is matched withattr { set last withattr set curattr [lindex [split [string trim $value] ":"] 0] if {[lindex $stack 0]=="fmt"} { #it's a format attribute lappend attrs($media.$proto.$curfmt) $curattr lappend withattrs($media.$proto.$curfmt) [string trim $value] } } #noattr is for when we want to specify an action to perform #when an attribute is *not* present. noattr { set last noattr set curnoattr [string trim $value] if {[lindex $stack 0]=="fmt"} { #it's a format attribute set noattrlist($tool.$media.$proto.$curfmt) \ "$noattrlist($tool.$media.$proto.$curfmt) $curnoattr" } else { #it's a protocol attribute lappend noattrlist($tool.$media.$proto) $curnoattr } } #set default attributes/attribute values def { if {([string trim $value]=="true")&&\ ([lindex $stack 0]=="attr")} { set last defattr if {[lindex $stack 1]=="fmt"} { #it's a format attribute if {[lsearch -glob $defattrlist($media.$proto.$curfmt) \ "$curattr:*"]==-1} { lappend defattrlist($media.$proto.$curfmt) $curattr } } else { #it's a protocol attribute #not sure this makes sense, but will allow it here #and ignore it later... if {[lsearch -glob $defattrlist($media.$proto) \ "$curattr:*"]==-1} { lappend defattrlist($media.$proto) $curattr } } } elseif {([string trim $value " "]=="true")&&\ ([lindex $stack 0]=="attrvalue")} { if {[lindex $stack 1]=="attr"} { if {[lindex $stack 2]=="fmt"} { #it's a format attribute set ix [lsearch $defattrlist($media.$proto.$curfmt) \ $curattr] if {$ix==-1} { set ix [lsearch -glob \ $defattrlist($media.$proto.$curfmt) \ "$curattr:*"] } if {$ix==-1} { lappend defattrlist($media.$proto.$curfmt) \ $curattr:$curattrvalue } else { set defattrlist($media.$proto.$curfmt) \ [lreplace $defattrlist($media.$proto.$curfmt) \ $ix $ix $curattr:$curattrvalue] } } else { #it's a protocol attribute set ix [lsearch $defattrlist($media.$proto) \ $curattr] if {$ix==-1} { set ix [lsearch -glob $defattrlist($media.$proto) \ "$curattr:*"] } if {$ix==-1} { lappend defattrlist($media.$proto) \ $curattr:$curattrvalue } else { set defattrlist($media.$proto) \ [lreplace $defattrlist($media.$proto) \ $ix $ix $curattr:$curattrvalue] } } } } elseif {[lindex $stack 0]=="inputvalue"} { puts "default inputvalue" } else { puts "default tag outside of attribute or attribute value" return -1; } } hidden { if {[lindex $stack 0]=="attr"} { } elseif {[lindex $stack 0]=="attrvalue"} { } elseif {[lindex $stack 0]=="fmt"} { # puts [array names tmpfmts] set tmpfmts($media.$proto.$curfmt) "" } } attrname { if {[lindex $stack 0]=="attr"} { set attrnames($curattr) $value # puts "attrname($curattr)=$attrnames($curattr)" } else { catch {puts "parse error: attrname with no current attribute"} } } inputvalue { set last inputvalue } attrvalue { set last attrvalue regsub -all " " $value "\\ " curattrvalue if {[lindex $stack 0]=="attr"} { if {[lindex $stack 1]=="fmt"} { # puts $attrs($media.$proto.$curfmt) #it's a format attribute if {[lindex $attrs($media.$proto.$curfmt) end]\ ==$curattr} { set len [llength $attrs($media.$proto.$curfmt)] set attrs($media.$proto.$curfmt) \ [lrange $attrs($media.$proto.$curfmt) 0 \ [expr $len -2]] lappend attrs($media.$proto.$curfmt) \ $curattr:$curattrvalue } else { lappend attrs($media.$proto.$curfmt) \ $curattr:$curattrvalue } } else { #it's a protocol attribute if {[lindex $attrs($media.$proto) end]==$curattr} { set len [llength $attrs($media.$proto)] set attrs($media.$proto) \ [lrange $attrs($media.$proto) 0 \ [expr $len -2]] lappend attrs($media.$proto) \ $curattr:$curattrvalue } else { lappend attrs($media.$proto) \ $curattr:$curattrvalue } } } else { catch {puts "parse error: attrvalue with no current attribute\n $value"} } } attrvaluename { if {[lindex $stack 0]=="attrvalue"} { set attrvaluenames($curattr:$curattrvalue) $value } else { catch {puts "parse error: attrvaluename with no current attrvalue\n $value\n $stack $curattr:$curattrvalue"} } } macro { if {([lindex $stack 0]=="attr")||\ ([lindex $stack 0]=="attrvalue")||\ ([lindex $stack 0]=="fmt")} { set last macro set curmacro [string trim $value " "] } else { catch {puts "parse error: macro outside of attribute or fmt"} } } value { if {[lindex $stack 0]=="macro"} { if {[lindex $stack 2]=="fmt"} { #stack is fmt,attr,macro set macrokeys($tool.$media.$proto.$curfmt.$curattr) $curmacro set macros($tool.$media.$proto.$curfmt.$curattr) $value } elseif {[lindex $stack 2]=="attr"} { #stack is fmt,attr,attrvalue,macro set macrokeys($tool.$media.$proto.$curfmt.$curattr) $curmacro set macros($tool.$media.$proto.$curfmt.$curattr) $value } elseif {[lindex $stack 1]=="attr"} { #stack is ??,attr,macro set macrokeys($tool.$media.$proto.$curattr) $curmacro set macros($tool.$media.$proto.$curattr) $value } elseif {[lindex $stack 1]=="fmt"} { #stack is fmt,macro set macrokeys($tool.$media.$proto.$curfmt) $curmacro set macros($tool.$media.$proto.$curfmt) $value } } else { catch {puts "parse error: macrovalue outside of macro"} } } create { if {[string trim $value " "]=="no"} { set create no } } } } foreach currule $currules { set ruleix [lsearch $rules $currule] if {$ruleix==-1} { set rules "$rules $currule" set mappings($currule) [list $curexec($currule)] } else { set newtool [lindex $curexec($currule) 0] set done 0 set ix 0 foreach mapping $mappings([lindex $rules $ruleix]) { set oldtool [lindex $mapping 0] if {[string compare $oldtool $newtool]==0} { set done 1 #replace the old rule with the new one set mappings($currule) [concat \ [lrange $mappings($currule) 0 [expr $ix-1]] \ [list $curexec($currule)] \ [lrange $mappings($currule) [expr $ix+1] end]] break } incr ix } if {$done==0} { lappend mappings($currule) $curexec($currule) } } if {([lsearch $createrules $currule]==-1)&&($create=="yes")} { set createrules "$createrules $currule" set protos($currule) $proto set fmts($currule) $tmpfmts($currule) } set protonames($proto) $protoname set fmtnames($tmpfmts($currule)) $tmpfmtnames($currule) } } proc add_to_known_media {media} { global medialist mediadata if {[lsearch $medialist $media]==-1} { lappend medialist $media set mediadata(icon:$media) unknown set mediadata(text:$media) $media } } proc add_tool_cryptflag {tool cryptflag} { global tooldata set tooldata(cryptflag:$tool) $cryptflag } proc add_media_icon {media icon} { global medialist mediadata if {$mediadata(icon:$media)=="unknown"} { set mediadata(icon:$media) $icon } else { catch {puts "Warning: icon $mediadata(icon:$media) overridden by icon $icon for media $media"} set mediadata(icon:$media) $icon } } proc add_media_text {media text} { global medialist mediadata if {$mediadata(text:$media)==$media} { set mediadata(text:$media) $text } else { catch {puts "Warning: text $mediadata(text:$media) overridden by text $text for media $media"} set mediadata(text:$media) $text } } proc find_tool {tool} { global env tcl_platform if {$tcl_platform(platform) == "windows"} { set path [split $env(PATH) ";"] set tool $tool.exe } else { set path [split $env(PATH) ":"] } foreach dir $path { if {[file executable $dir/$tool]==1} { return $dir/$tool } } return "" } proc wcsearch {rules base} { #wcsearch checks to see if there is any rule which contains a wildcard #format which might match if exact matches have failed set wclist "" foreach rule $rules { if {[string first "$base.*" $rule]==0} { #success (subject to a suitable attribute telling us what to do) set start [string length "$base.*"] lappend wclist [string range $rule $start end] } } return $wclist } proc start_media_tool {aid media proto fmt attrlist} { global rules global mappings global attrflags global withattrs global tool_state global macrovalues foreach macrovalue [array names macrovalues] { unset macrovalues($macrovalue) } if {([lsearch $rules "$media.$proto.$fmt"]==-1) && \ ([wcsearch $rules "$media.$proto"]=="")} { msgpopup "Unknown protocol or format" "The session you tried to join contains a media \"$media\" with protocol \"$proto\" and format \"$fmt\". I have no plug-in module that defines a $media tool for this. To join this session you need a plug-in module for this combination of media, protocol and format and a media tool capable of receiving the data.\n\nSee \"Help\" for more details of plug-in modules" return 0 } else { if {[lsearch $rules "$media.$proto.$fmt"]==-1} { #there were no exact matches on the format, but a wildcard #match was possible (typically an RTP dynamic payload type) set wclist [wcsearch $rules "$media.$proto"] set match 0 # puts $wclist # puts "got a wildcard match" foreach wc $wclist { set needattr "" catch {set needattr $withattrs($media.$proto.*$wc)} if {$needattr==""} { continue } foreach wa $needattr { set withattr [expand_var $wa $wc $fmt] set tmp $withattr # puts $withattr while {[string first "*(" $tmp]!=-1} { set tmp [remove_wc_vars $tmp] } # puts $tmp foreach attr $attrlist { # puts "string match >$tmp< >$attr<" if {[string match $tmp $attr]==1} { set match 1 break } } if {$match==1} { break } } if {$match==1} { break } } if {$match==1} { #at this stage wc holds the name of the wildcard and #wa holds the relevant "withattr" line from the plugin #now we need to match against the actual attributes.. #(this is really ugly) # puts "SUCCESS\nwc:$wc\nwa:$wa" # puts "tmp:$tmp" foreach attrflag [array names attrflags] { # puts "attrflag:$attrflag" # puts "match: *.$media.$proto.*$wc.$wa" if {[string match "*.$media.$proto.\*$wc.$wa" $attrflag]==1} { # puts "flags index: $attrflag" # puts "flags: $attrflags($attrflag)" set tool [find_tool [lindex [split $attrflag "."] 0]] if {$tool==""} { continue } # puts "tool: $tool" set macrovalues([string trim $wc "()"]) $fmt set fmt "*$wc" lappend attrlist $wa set rule $mappings($media.$proto.*$wc) break } } } else { msgpopup "Unknown protocol or format" "The session you tried to join contains a media \"$media\" with protocol \"$proto\" and format \"$fmt\". I have no plug-in module that defines a $media tool for this. To join this session you need a plug-in module for this combination of media, protocol and format and a media tool capable of receiving the data.\n\nSee \"Help\" for more details of plug-in modules" return 0 } } else { #we got a format we know we support set rule $mappings($media.$proto.$fmt) } set rulelist {} foreach subrule $rule { set tool [find_tool [lindex $subrule 0]] if {$tool==""} { # catch {puts "the tool [lindex $subrule 0] is not installed"} } else { set tmp enabled # catch {puts "$media.$proto.$fmt.[lindex $subrule 0]"} catch {set tmp $tool_state($media.$proto.$fmt.[lindex $subrule 0])} if {$tmp=="enabled"} { lappend rulelist $subrule } } } if {[llength $rulelist]==0} { set toollist {} foreach subrule $rule { lappend toollist [lindex $subrule 0] } msgpopup "No suitable $media tool installed" "The session you tried to join contains a media \"$media\" for which I can find no suitable tool installed. Suitable tools that I know about would include:\n$toollist\nNone of these is in your command path." # puts "no tools are installed for $media" return 0; } elseif {[llength $rulelist]>1} { # set toollist {} # set newrules {} # foreach rule [list_reverse $rulelist] { # set tool [lindex $rule 0] # if {[lsearch -exact $toollist $tool]>=0} { # #we have two rules for the same tool # #skip this rule # } else { # lappend newrules $rule # } # lappend toollist $tool # } # if {[llength $newrules]>1} { # select_tool_for_media $aid $media $proto $fmt \ # $newrules $attrlist # return 0 # } else { # set rule [lindex $newrules 0] # } select_tool_for_media $aid $media $proto $fmt \ $rulelist $attrlist return 0 } else { set rule [lindex $rulelist 0] } } return [apply_startup_rule $aid $media $proto $fmt $rule $attrlist] } proc list_reverse {list} { set newlist {} foreach el $list { set newlist "[list $el] $newlist" } string trim $newlist return $newlist } proc apply_startup_rule {aid media proto fmt rule attrlist} { global sd_sess tcl_platform global sd_$media global macros macrokeys global attrflags noattrflags noattrlist macrovalues global youremail global ldata global debug1 global tooldata encryptionflag # puts apply_startup_rule # puts "media: $media" # puts "proto: $proto" # puts "fmt: $fmt" # puts "rule: $rule" # puts "attrlist: $attrlist" log "starting tool for $media at [getreadabletime]" set rule [string trim $rule "\{\}"] set tool [lindex $rule 0] # replaced next line as it adds {} around elements of cmd line. New one doesn't # set rule [lrange $rule 1 end] set rule [ string range $rule [string wordend $rule 0] end] foreach noattr \ "$noattrlist($tool.$media.$proto) $noattrlist($tool.$media.$proto.$fmt)" { set nat($noattr) 1 } set attrs "" # puts $attrlist foreach attr $attrlist { set tmp "" catch {set tmp $attrflags($tool.$media.$proto.$attr)} if {$tmp==""} { catch {set tmp $attrflags($tool.$media.$proto.$fmt.$attr)} } if {$tmp!=""} { catch {unset nat([lindex [split $attr ":"] 0])} } set attrs "$attrs $tmp" } set tmp "" foreach attr [array names nat] { catch {set tmp $noattrflags($tool.$media.$proto.$attr)} if {$tmp==""} { catch {set tmp $noattrflags($tool.$media.$proto.$fmt.$attr)} } set attrs "$attrs $tmp" } set tmp "" catch { set macrokey $macrokeys($tool.$media.$proto.$fmt) set tmp $macros($tool.$media.$proto.$fmt) } if {$tmp!=""} { set macrovalues($macrokey) [expand_macro $tmp ""] } foreach attr $attrlist { set key [lindex [split $attr ":"] 0] set tmp "" catch { set macrokey $macrokeys($tool.$media.$proto.$key) set tmp $macros($tool.$media.$proto.$key) } if {$tmp==""} { catch { set macrokey $macrokeys($tool.$media.$proto.$fmt.$key) set tmp $macros($tool.$media.$proto.$fmt.$key) } } if {$tmp!=""} { set macrovalues($macrokey) [expand_macro $tmp [lindex [split $attr ":"] 1]] } } set ttl $sd_sess(ttl) set sessname \"$sd_sess(name)\" set address [set sd_[set media](address)] set layers [set sd_[set media](layers)] set port [set sd_[set media](port)] set chan [get_channel $sd_sess(sess_id)] set cryptkey \"[set sd_[set media](mediakey)]\" set rule "$tool $attrs $rule" if {$debug1} { puts "fixing rule: $rule" } if {([info exists tooldata(cryptflag:$tool)] != 1) && $cryptkey != "\"\""} { msgpopup "Encryption Not Supported" "The tool you are using ($tool) does not seem to support encryption. You may be unable to decrypt the $media media stream" } if {[info exists tooldata(cryptflag:$tool)] && $cryptkey != "\"\""} { set encryptionflag $tooldata(cryptflag:$tool) } else { set encryptionflag "" } set rule [fix_up_plugin_rule $rule] if {$debug1} { puts "fixing rule: $rule" } set rule [fix_up_plugin_rule $rule] eval "set rule \"$rule\"" if {$debug1} { catch {puts \"$rule\"} catch {eval puts \"$rule\"} } if {$tcl_platform(platform) == "windows"} { set pid [eval exec $rule &] } else { set pid [run_program $rule] } #keep track of the pid so we can see if the tools are still running... for {set i 0} {$i<$ldata($aid,medianum)} {incr i} { if {$ldata($aid,$i,media)==$media} { set ldata($aid,$i,pid) $pid break } } return 1 } proc expand_macro {macro value} { set ix [string first "\$(VALUE)" $macro] if {$ix==-1} {return $macro} set first [string range $macro 0 [expr $ix-1]] set rest [string range $macro [expr $ix+8] end] return "$first$value$rest" } proc expand_var {macro variable value} { set ix [string first "\$$variable" $macro] if {$ix==-1} {return $macro} set first [string range $macro 0 [expr $ix-1]] set len [string length "\$$variable"] set rest [string range $macro [expr $ix+$len] end] return "$first$value$rest" } proc remove_wc_vars {str} { set ix [string first "*(" $str] set first [string range $str 0 [expr $ix]] set rest [string range $str [expr $ix+2] end] set ix [string first ")" $rest] set rest [string range $rest [expr $ix+1] end] return $first$rest } proc fix_up_plugin_rule {rule} { global macrovalues global encryptionflag set vars [split $rule "\$"] set newrule [lindex $vars 0] foreach var [lrange $vars 1 end] { if {[string range $var 0 0]=="("} { set tmp [split [string range $var 1 end] ")"] if {[llength $tmp]==2} { set varname [lindex $tmp 0] set rest [lindex $tmp 1] switch $varname { TTL { set newrule "$newrule\$ttl$rest" } LAYERS { set newrule "$newrule\$layers$rest" } SESSNAME { set newrule "$newrule\$sessname$rest" } ADDRESS { set newrule "$newrule\$address$rest" } PORT { set newrule "$newrule\$port$rest" } PROTO { set newrule "$newrule\$proto$rest" } FMT { set newrule "$newrule\$fmt$rest" } CHAN { set newrule "$newrule\$chan$rest" } YOUREMAIL { set newrule "$newrule\$youremail$rest" } CRYPTKEY { if { $encryptionflag != "" } { set newrule "$newrule $encryptionflag \$cryptkey$rest" } else { set newrule "$newrule$rest" } } default { if {[info exists macrovalues($varname)]} { set newrule \ "$newrule$macrovalues($varname)$rest" } else { set newrule "$newrule$rest" } } } } else { catch {puts "rule parse error"} return -1 } } else { set newrule "$newrule\$$var" } } return $newrule } proc select_tool_for_media {aid media proto fmt rulelist attrlist} { set win .st$media catch {destroy $win} toplevel $win wm title $win "Select a tool" frame $win.f -relief groove -borderwidth 2 pack $win.f -side top label $win.f.l -text "More than one $media tool is available" pack $win.f.l -side top message $win.f.msg -aspect 300 -text "To join the $media part of this session, you could use one of several tools. Please select the tool you wish to use." pack $win.f.msg -side top -fill x -expand true frame $win.f.f pack $win.f.f -side top set bnum 0 global startrule set startrule($media) [lindex $rulelist 0] foreach rule $rulelist { radiobutton $win.f.f.$bnum -text [lindex $rule 0] \ -variable startrule($media) -value $rule -highlightthickness 0 pack $win.f.f.$bnum -side left incr bnum } frame $win.f.f2 pack $win.f.f2 -side top -fill x -expand true button $win.f.f2.start -text "Start tool" \ -command "apply_startup_rule $aid $media $proto $fmt \[set startrule($media)\] \"$attrlist\";destroy $win" -highlightthickness 0 tixAddBalloon $win.f.f2.start Button [tt "Click here to start up the tool you've selected"] pack $win.f.f2.start -side left -fill x -expand true button $win.f.f2.cancel -text "Cancel" -command "destroy $win" \ -highlightthickness 0 tixAddBalloon $win.f.f2.cancel Button [tt "Click here to cancel starting up this tool"] pack $win.f.f2.cancel -side left -fill x -expand true } proc is_creatable {media} { global createrules protos foreach rule $createrules { if {[string first $media $rule]==0} { return 1 } } return 0 } proc get_media_protos {media} { global createrules protos set protolist {} foreach rule $createrules { if {[string first $media $rule]==0} { if {[lsearch $protolist $protos($rule)]==-1} { lappend protolist $protos($rule) } } } return $protolist } proc get_proto_name {proto} { global protonames set rtn $proto catch {set rtn $protonames($proto)} return $rtn } proc get_media_fmts {media proto} { global createrules fmts set fmtlist {} foreach rule $createrules { if {[string first $media.$proto $rule]==0} { if {([lsearch $fmtlist $fmts($rule)]==-1)&&($fmts($rule)!="")} { lappend fmtlist $fmts($rule) } } } return $fmtlist } proc get_fmt_name {fmt} { global fmtnames set rtn $fmt catch {set rtn $fmtnames($fmt)} return $rtn } proc get_proto_attrs {media proto} { global attrs return $attrs($media.$proto) } proc get_fmt_attrs {media proto fmt} { global attrs return $attrs($media.$proto.$fmt) } proc get_attr_name {attr} { global attrnames set rtn $attr catch {set rtn $attrnames($attr)} return $rtn } proc get_attrvalue_name {attr value} { global attrvaluenames set rtn $value catch {set rtn $attrvaluenames($attr:$value)} return $rtn } proc get_max_layers {media proto fmt} { global fmtlayers return $fmtlayers($media.$proto.$fmt) } proc pref_tools {cmd {arg1 {}} {arg2 {}} {arg3 {}}} { global prefs tool_state switch $cmd { copyin { foreach i [array names prefs "tools_*"] { unset prefs($i) } foreach i [array names tool_state] { set prefs(tools_$i) $tool_state($i) } } copyout { foreach i [array names tool_state] { unset tool_state($i) } foreach i [array names prefs "tools_*"] { if {[regsub "^tools_(.*)$" $i {\1} tmp]} { set tool_state($tmp) $prefs($i) } } } defaults { foreach i [array names prefs "tools_*"] { unset prefs($i) } } create { select_startup_rule $arg1 $arg2 $arg3 return "Tools" } balloon { return "Select the tools that you would like to use when joining a session" } save { set lst {} catch {set lst [array names tool_state]} foreach rule $lst { regsub -all {\)} $rule {\\)} rule puts $arg1 [list set tool_state($rule) disabled] } } } } proc select_startup_rule {win width height} { global rules mappings font prefs # catch {destroy .rules} # toplevel .rules # wm title .rules "Select Tools to Start" frame $win -borderwidth 3 -relief raised frame $win.setw -borderwidth 0 -height 1 -width $width pack $win.setw -side top # pack $win -side top message $win.msg -aspect 600 -text "The following media formats have more than one tool available to decode them" pack $win.msg -side top -fill x bind $win.msg {prefs_help [tt "Click on the tool name to enable or disable it for the particular protocol and format if you don't wish to be prompted."]} bind $win.msg {prefs_help ""} set lines 0 foreach rule $rules { if {[llength $mappings($rule)]>1} { incr lines } } set lh 17 frame $win.f pack $win.f -side top canvas $win.f.c -width 400 -height 220 \ -yscrollcommand "$win.f.sb set" \ -scrollregion "0 0 400 [expr ($lines+1)*$lh]" pack $win.f.c -side left scrollbar $win.f.sb -command "$win.f.c yview" pack $win.f.sb -fill y -expand true set ix 1 $win.f.c create text 10 0 -anchor nw -text "Media" -font $font $win.f.c create text 60 0 -anchor nw -text "Proto" -font $font $win.f.c create text 100 0 -anchor nw -text "Format" -font $font $win.f.c create text 150 0 -anchor nw -text "Available Tools" -font $font $win.f.c create line 0 15 400 15 set dislst {} catch {set dislst [array names prefs "tools_*"]} foreach rule $rules { if {[llength $mappings($rule)]>1} { set lst [split $rule "."] set media [lindex $lst 0] set proto [get_proto_name [lindex $lst 1]] set fmt [get_fmt_name [lindex $lst 2]] $win.f.c addtag m.$rule withtag \ [$win.f.c create text 10 [expr $ix*$lh] -anchor nw\ -text $media -font $font] $win.f.c addtag p.$rule withtag \ [$win.f.c create text 60 [expr $ix*$lh] -anchor nw\ -text $proto -font $font] $win.f.c addtag f.$rule withtag \ [$win.f.c create text 100 [expr $ix*$lh] -anchor nw\ -text $fmt -font $font] set mx 150 foreach map $mappings($rule) { set tool [lindex $map 0] $win.f.c addtag b$tool.$rule withtag \ [$win.f.c create rectangle [expr $mx-5] [expr ($ix*$lh)-1] \ [expr $mx+35] [expr (($ix+1)*$lh)-3 ] -fill white \ -outline black] $win.f.c addtag $tool.$rule withtag \ [$win.f.c create text $mx [expr $ix*$lh] -anchor nw\ -text $tool -font $font] $win.f.c bind b$tool.$rule \ "$win.f.c itemconfigure b$tool.$rule -fill black;\ $win.f.c itemconfigure $tool.$rule -fill white" $win.f.c bind b$tool.$rule \ "$win.f.c itemconfigure b$tool.$rule -fill white;\ $win.f.c itemconfigure $tool.$rule -fill black" $win.f.c bind $tool.$rule \ "$win.f.c itemconfigure b$tool.$rule -fill black;\ $win.f.c itemconfigure $tool.$rule -fill white" $win.f.c bind $tool.$rule \ "$win.f.c itemconfigure b$tool.$rule -fill white;\ $win.f.c itemconfigure $tool.$rule -fill black" $win.f.c bind $tool.$rule <1> \ "toggle_tool_state $win.f.c $tool $rule \"$map\" $mx $ix $lh" $win.f.c bind b$tool.$rule <1> \ "toggle_tool_state $win.f.c $tool $rule \"$map\" $mx $ix $lh" if {[lsearch $dislst tools_$rule.$tool]>=0} { unset prefs(tools_$rule.$tool) toggle_tool_state $win.f.c $tool $rule $map $mx $ix $lh } incr mx 50 } incr ix } } # frame $win.f2 -borderwidth 2 -relief groove # pack $win.f2 -side top -fill x # button $win.f2.save -borderwidth 1 -relief raised -text "Save Preferences"\ # -command {destroy .rules;save_prefs} # pack $win.f2.save -side left -fill x -expand true # button $win.f2.ok -borderwidth 1 -relief raised -text "OK"\ # -command {destroy .rules} # pack $win.f2.ok -side left -fill x -expand true frame $win.f2 -borderwidth 0 -relief flat -width 1 -height \ [expr $height - [winfo reqheight $win]] pack $win.f2 -side top } proc toggle_tool_state {canv tool rule map mx ix lh} { global prefs set lst {} catch {set lst [array names prefs "tools_*"]} if {[lsearch $lst tools_$rule.$tool]==-1} { #the map is not disabled set prefs(tools_$rule.$tool) disabled $canv addtag dis1$tool.$rule withtag \ [$canv create line [expr $mx-5] [expr ($ix*$lh)-1] \ [expr $mx+35] [expr (($ix+1)*$lh)-3 ] -width 2] $canv addtag dis2$tool.$rule withtag \ [$canv create line [expr $mx+35] [expr ($ix*$lh)-1] \ [expr $mx-5] [expr (($ix+1)*$lh)-3 ] -width 2] $canv bind dis1$tool.$rule <1> \ "toggle_tool_state $canv $tool $rule \"$map\" $mx $ix $lh" $canv bind dis2$tool.$rule <1> \ "toggle_tool_state $canv $tool $rule \"$map\" $mx $ix $lh" $canv bind dis1$tool.$rule \ "$canv itemconfigure b$tool.$rule -fill black;\ $canv itemconfigure $tool.$rule -fill white" $canv bind dis1$tool.$rule \ "$canv itemconfigure b$tool.$rule -fill white;\ $canv itemconfigure $tool.$rule -fill black" $canv bind dis2$tool.$rule \ "$canv itemconfigure b$tool.$rule -fill black;\ $canv itemconfigure $tool.$rule -fill white" $canv bind dis2$tool.$rule \ "$canv itemconfigure b$tool.$rule -fill white;\ $canv itemconfigure $tool.$rule -fill black" } else { $canv delete dis1$tool.$rule $canv delete dis2$tool.$rule unset prefs(tools_$rule.$tool) } } set invited_sessions {} set qdurs {"5 mins" "15 mins" "half hour" "an hour"} set qdurt {300 900 1800 3600} #set qpurp {"Two-way call" "Group Chat" "Small Meeting" "Large Meeting"} set qpurp {"Group Chat" "Small Meeting" "Large Meeting"} #set qpmway {0 1 1 1} set qpmway {1 1 1} #Notes: #SDR can be both a sip client and server # #sip_requests holds the list of request ids that a client has outstanding #sip_request_status holds the status of each of these # possible values are: # unknown - we sent a request and didn't get anything back yet # progressing - we sent a request and got back a 100 trying reply # ringing - we sent a request and the remote end says its ringing # connected - we got back a 200 response # declined - we got back a failure and have no more options for this call # hungup - we hung up on a call we initiated. # #sip_invites holds the list of request ids that a server has outstanding #sip_invite_status holds the status of each of these # possible values are: # ringing - we alerted the user but no response yet # accepted - we sent a 200 response # connected - we sent a 200 response and got an ACK # failed - we sent more than ten 200 responses and got no ACK # refused - we sent a failure response # done - we sent a failure response and got an ACK or didn't get an # ACK after resending the response more than ten times. proc qcall {} { global scope qdurs qdurt qpurp qpmway medialist send youremail catch {destroy .qc} if {$youremail==""} { enter_phone_details qcall return } toplevel .qc wm title .qc "Sdr: Quick Call" posn_win .qc frame .qc.f -borderwidth 2 -relief groove pack .qc.f -side top new_mk_session_name .qc.f new set scope admin frame .qc.f.l -borderwidth 0 pack .qc.f.l -side left -anchor nw label .qc.f.l.l -text "Expected Duration: " pack .qc.f.l.l -side top menubutton .qc.f.l.m -menu .qc.f.l.m.menu -text [lindex $qdurs 0] -relief raised -borderwidth 1 tixAddBalloon .qc.f.l.m MenuButton [tt "Select how long your quick \ call is likely to last. \n\nThis is the time that the quick call \ will be advertised in the main session window under private \ sessions - the session announcement will only be available to \ people you invite to join the session"] global qdur set qdur [lindex $qdurt 0] pack .qc.f.l.m -side top menu .qc.f.l.m.menu -tearoff 0 for {set i 0} {$i < [llength $qdurs]} {incr i} { .qc.f.l.m.menu add radiobutton -label [lindex $qdurs $i] \ -variable qdur -value [lindex $qdurt $i] \ -command ".qc.f.l.m configure -text \"[lindex $qdurs $i]\"" } label .qc.f.l.l2 -text "Purpose:" pack .qc.f.l.l2 -side top menubutton .qc.f.l.m2 -menu .qc.f.l.m2.menu -text [lindex $qpurp 0] -relief raised -borderwidth 1 tixAddBalloon .qc.f.l.m2 MenuButton [tt "Select the purpose of the quick call. This will be given to the people you invite to partake in the quick call"] global qpur set qpur [lindex $qpurp 0] pack .qc.f.l.m2 -side top menu .qc.f.l.m2.menu -tearoff 0 for {set i 0} {$i < [llength $qpurp]} {incr i} { .qc.f.l.m2.menu add radiobutton -label [lindex $qpurp $i] \ -variable qpur -value [lindex $qpurp $i] \ -command ".qc.f.l.m2 configure -text \"[lindex $qpurp $i]\";qset_config_scope \$qpur" } frame .qc.f.l.f -borderwidth 0 pack .qc.f.l.f -side top new_mk_session_admin .qc.f.l.f.admin new $scope qset_config_scope $qpur foreach i $medialist { set send($i) 0 } set send(audio) 1 new_mk_session_media .qc.f.media new admin 0 frame .qc.f.buttons -borderwidth 2 -relief groove pack .qc.f.buttons -side top -fill x -expand true button .qc.f.buttons.invite -text "Invite" -command {set invaid [qcreate];if {$invaid!=0} { popup $invaid $ifstyle(view) advert;embed_invite $invaid .desc$invaid.f;destroy .qc}} tixAddBalloon .qc.f.buttons.invite Button [tt "Click here to invite people to participate in the session"] pack .qc.f.buttons.invite -side left -fill x -expand true button .qc.f.buttons.dismiss -text "Cancel" -command {destroy .qc} tixAddBalloon .qc.f.buttons.dismiss Button [tt "Click here to cancel creating a quick call"] pack .qc.f.buttons.dismiss -side left -fill x -expand true move_onscreen .qc } proc qset_config_scope {purpose} { if {$purpose=="Two-way call"} { pack unpack .qc.f.l.f.admin } else { pack .qc.f.l.f.admin -side top } } set qseq 0 proc qcreate {} { #create a session that we don't publically announce to anyone #so we can do a private invitation global qseq qpur qdur zone ttl media_attr media_fmt media_proto global media_layers global yourphone youremail medialist send ldata sesstype global sdrversion global sessionkey #edmund global mediaenc set aid priv$qseq incr qseq if {[get_new_session_name .qc.f]==""} { errorpopup "No Session Name" "You must give the session a name" return 0 } set ldata($aid,session) [get_new_session_name .qc.f] set ldata($aid,desc) $qpur set ldata($aid,phonelist) \"$yourphone\" set ldata($aid,emaillist) \"$youremail\" set ldata($aid,starttime) [unix_to_ntp [gettimeofday]] set ldata($aid,endtime) [unix_to_ntp [expr [gettimeofday] + $qdur]] set ldata($aid,no_of_times) 1 set ldata($aid,time0,no_of_rpts) 0 set ldata($aid,starttime,0) [unix_to_ntp [gettimeofday]] set ldata($aid,endtime,0) [unix_to_ntp [expr [gettimeofday] + $qdur]] set ldata($aid,method) invite set ldata($aid,type) meeting set ldata($aid,tool) "sdr $sdrversion" set ldata($aid,vars) "tool:$ldata($aid,tool)\ntype:$ldata($aid,type)" set ldata($aid,key) "" set ldata($aid,lastheard) [gettimeofday] set ldata($aid,sap_addr) "" set ldata($aid,sap_port) "" set ldata($aid,started) 0 set ldata($aid,list) "" set ldata($aid,trust) sip set medianum 0 foreach media $medialist { if {$send($media)==1} { set ldata($aid,$medianum,media) $media set ldata($aid,$medianum,port) [generate_port $media] set ldata($aid,$medianum,addr) [generate_address $zone(base_addr,$zone(cur_zone)) $zone(netmask,$zone(cur_zone))] set ldata($aid,$medianum,fmt) $media_fmt($media) set ldata($aid,$medianum,proto) $media_proto($media) set ldata($aid,$medianum,layers) $media_layers($media) set ldata($aid,$medianum,ttl) $zone(ttl,$zone(cur_zone)) set ldata($aid,$medianum,vars) "" #edmund if {$mediaenc($media) == 1} { set ldata($aid,$medianum,mediakey) $sessionkey($media) } else { set ldata($aid,$medianum,mediakey) "" } foreach attr [array names media_attr] { set m [lindex [split $attr ","] 0] set a [lindex [split $attr ","] 1] if {$m==$media} { if {$media_attr($attr)==1} { set ldata($aid,$medianum,vars) \ "$ldata($aid,$medianum,vars) $a" } elseif {($media_attr($attr)!=0)&&\ ($media_attr($attr)!="")} { set ldata($aid,$medianum,vars) \ "$ldata($aid,$medianum,vars) $a:$media_attr($attr)" } } } incr medianum } } if {$medianum==0} { errorpopup "No Media Selected" "You must select at least one media" return 0 } set ldata($aid,medianum) $medianum set ldata($aid,creator) [getusername] set ldata($aid,createtime) [gettimeofday] set ldata($aid,modtime) [gettimeofday] set ldata($aid,createaddr) [gethostaddr] set ldata($aid,uri) 0 set ldata($aid,multicast) $ldata($aid,0,addr) set ldata($aid,ttl) $ldata($aid,0,ttl) set ldata($aid,tfrom) [fixtime [gettime \ [ntp_to_unix $ldata($aid,starttime)]]] set ldata($aid,tfrom,0) $ldata($aid,tfrom) set ldata($aid,tto) [fixtime [gettime \ [ntp_to_unix $ldata($aid,endtime)]]] set ldata($aid,tto,0) $ldata($aid,tto) set ldata($aid,source) $ldata($aid,createaddr) set ldata($aid,heardfrom) [gethostaddr] set ldata($aid,theard) [fixtime [gettime [gettimeofday]]] return $aid } proc invite {aid} { global invited_sessions ldata catch {destroy .inv} toplevel .inv # puts "C aid:$aid" wm title .inv "Sdr: Invite User" if {$invited_sessions=={}} { set invited_sessions $aid } else { if {[lsearch $invited_sessions $aid]==-1} { set invited_sessions "$invited_sessions $aid" } } foreach session $invited_sessions { set wname .inv.$session frame $wname -borderwidth 2 -relief groove pack $wname -side top label $wname.l -text $ldata($session,session) pack $wname.l -side top frame $wname.f pack $wname.f -side top -fill x -expand true entry $wname.f.e -width 30 -relief sunken \ -bg [option get . entryBackground Sdr] bind $wname.f.e "send_sip \[$wname.f.e get\] \[$wname.f.e get\] \"$session\" 0 0 0 0 NONE" pack $wname.f.e -side left -fill x -expand true button $wname.f.inv -text "Invite" -command "send_sip \[$wname.f.e get\] \[$wname.f.e get\] \"$session\" 0 0 0 0 NONE" pack $wname.f.inv -side left sip_list_invitees $wname $session } frame .inv.f -borderwidth 2 -relief groove pack .inv.f -side top -fill x -expand true button .inv.f.dismiss -text "Dismiss" -command "destroy .inv" pack .inv.f.dismiss -side left -fill x -expand true } proc embed_invite {aid win} { global invited_sessions ldata frame $win.inv pack $win.inv -side top -before $win.f3 -fill x -expand true if {$invited_sessions=={}} { set invited_sessions $aid } else { if {[lsearch $invited_sessions $aid]==-1} { set invited_sessions "$invited_sessions $aid" } } set session $aid set wname $win.inv.$session frame $wname -borderwidth 2 -relief groove pack $wname -side top frame $wname.f0 pack $wname.f0 -side top -anchor nw -expand true -fill x label $wname.f0.l -text "Invite user (SIP URL or username@hostname)" pack $wname.f0.l -side left menubutton $wname.f0.m -text "Browse" -menu $wname.f0.m.m -relief raised menu $wname.f0.m.m make_address_book $wname.f0.m.m $wname.f.e $wname.f.inv pack $wname.f0.m -side right frame $wname.f pack $wname.f -side top -fill x -expand true entry $wname.f.e -width 30 -relief sunken \ -bg [option get . entryBackground Sdr] tixAddBalloon $wname.f.e Entry [tt "Enter username and machinename for user in the form: username@machine"] pack $wname.f.e -side left -fill x -expand true button $wname.f.inv -text "Invite" -highlightthickness 0 \ -state disabled \ -command "send_sip \[$wname.f.e get\] \[$wname.f.e get\] \"$session\" 0 $wname 0 0 0 NONE" foreach binding [bind Entry] { bind $wname.f.e $binding "[bind Entry $binding];break" } bind $wname.f.e "[bind Entry ];check_sip_url $wname.f.e $wname.f.inv;break" bind $wname.f.e "[bind Entry ];check_sip_url $wname.f.e $wname.f.inv;break" bind $wname.f.e "[bind Entry ];check_sip_url $wname.f.e $wname.f.inv;break" bind $wname.f.e "if {\[check_sip_url $wname.f.e $wname.f.inv\]==1} {send_sip \[$wname.f.e get\] \[$wname.f.e get\] \"$session\" 0 $wname 0 0 0 NONE} else {bell}" pack $wname.f.inv -side right sip_list_invitees $wname $session catch {pack unpack $win.f3.invite} } proc check_sip_url {entry button} { #try and ensure it's a valid URL before we let the user press the #invite button set url [$entry get] set res [sip_parse_url $url] set user [lindex $res 0]" set passwd [lindex $res 1] set addr [lindex $res 2] set port [lindex $res 3] set ttl [lindex $res 5] set maddr [lindex $res 6] set parts [split $addr "."] if {([llength $parts] <2)} {set addr ""} if {[string length [lindex $parts [expr [llength $parts] - 1]]]==0} { set addr "" } if {($user!="")&&($addr!="")} { $button configure -state normal return 1 } else { $button configure -state disabled return 0 } } proc sip_list_invitees {wname aid} { global sip_request_status sip_requests sip_request_user sip_request_aid foreach id $sip_requests { if {$sip_request_aid($id)==$aid} { set lid [join [split $id "."] "-"] if {$sip_request_status($id)!="declined"} { frame $wname.$lid pack $wname.$lid -side top label $wname.$lid.l1 -width 20 -text $sip_request_user($id) pack $wname.$lid.l1 -side left label $wname.$lid.l2 -width 10 -text $sip_request_status($id) pack $wname.$lid.l2 -side left } } } } proc sip_map_url_to_addr {location} { #if it was a URL other than a SIP one, this doesn't work... if {[string compare [string range $location 0 3] "sip:"]==0} { #it's a SIP URL #trim the URL set location [string range $location 6 end] set param [string first ";" $location] if {$param>=0} { #there was a parameter to the URL. #we don't understand parameters, so trim it off and continue #in the hope this is OK. set location [string range $location 0 [expr $param - 1]] } } set username [string trimleft [lindex [split $location "@"] 0] " "] set host [string trimright [lindex [split $location "@"] 1] " "] if {($username=="")||($host=="")} { msgpopup "Invalid Address" "Addresses must be of the form \"username@host\"" return 0 } set addr [lookup_host $host] if {$addr=="0.0.0.0"} { msgpopup "Invalid Address" "The hostname $host is not known" return 0 } return $addr } proc send_sip {dstuser user aid id win addr port ttl transport} { #dstuser is where the message is currently destined #user is the SIP name of the user at that location #the addr parameter should be zero when send_sip is called with #a new or modified request puts "send_sip: dstuser=$dstuser, user=$user, aid=$aid, id=$id, win=$win, addr=$addr, port=$port, ttl=$ttl" global youremail no_of_connections sip_request_status sip_request_addrs global sip_requests global sip_request_count sip_request_user sdrversion if {$addr!=0} { set addr [lookup_host $addr] } else { set res [sip_parse_url $dstuser] puts "$dstuser --> $res" set addr [lookup_host [lindex $res 2]] if {$addr=="0.0.0.0"} { msgpopup "Invalid Address" \ "The hostname [lindex $res 2] is not known" return 0 } set maddr [lindex $res 6] set port [lindex $res 3] set ttl [lindex $res 5] #fix up the URL by removing unnecessary parts set user "sip:[lindex $res 0]" set passwd [lindex $res 1] if {$passwd!=""} { set user "$user:$password" } set user "$user@[lindex $res 2]" if {$port!="5060"} { set user "user:$port" } if {$maddr!=""} { if {$ttl==0} {set ttl 16} set addr $maddr } set transport [lindex $res 4] if {$transport=="NONE"} {set transport "UDP"} } if {$addr==0} {return 0} #we can handle calls to multiple remote sites simultaneously #need to keep track of whether we've tried somewhere before set addrstatus "" catch { set addrstatus $sip_request_addrs($id,$addr) } puts "addrstatus: $addrstatus" if {$addrstatus==""} { set sip_request_addrs($id,$addr) "possible" } elseif {$addrstatus=="failed"} { return 0 } if {[lsearch $sip_requests $id]!=-1} { if {($sip_request_status($id)=="unknown") && ($sip_request_count($id)>20)} { sip_connection_fail $id "No response from remote site while trying to contact $sip_request_user($id)" return 0 } if {($sip_request_status($id)=="progressing") && ($sip_request_count($id)>20)} { sip_connection_fail $id "Unknown failure at remote site while trying to contact $sip_request_user($id)" return 0 } if {($sip_request_status($id)=="ringing") && ($sip_request_count($id)>30)} { sip_connection_fail $id "No response from $sip_request_user($id) to ringing at remote site" return 0 } if {($sip_request_status($id)=="connected")|| ($sip_request_status($id)=="declined")} { return 0 } if {($sip_request_status($id)=="hungup")} { sip_send_bye 0 $dstuser $user $id $cseq 1 return 0 } incr sip_request_count($id) } if {$id==0} { set id "[getpid]-[gettimeofday]@[gethostaddr]" set sip_request_count($id) 0 } set body [make_session $aid] set length [string length $body] set msg "INVITE $user SIP/2.0" if {$ttl>0} { set msg "$msg\r\nVia: SIP/2.0/UDP $addr;ttl=$ttl" } set msg "$msg\r\nVia: SIP/2.0/$transport [gethostaddr]" set msg "$msg\r\nCall-ID:$id" set msg "$msg\r\nCseq: 0 INVITE" set msg "$msg\r\nFrom:sip:$youremail" set msg "$msg\r\nTo:$user" set msg "$msg\r\nUser-Agent:sdr/$sdrversion" set msg "$msg\r\nContent-type:application/sdp" set msg "$msg\r\nContent-length:$length" set msg "$msg\r\n\r\n$body" debug $msg if {$transport=="UDP"} { if {[sip_user_pending $user $id $aid $win]==0} { if {[sip_send_udp $addr $ttl $port $msg]==0} { set no_of_connections($id) 1 if {($sip_request_status($id)=="progressing")||\ ($sip_request_status($id)=="ringing")} { set timer 5000 } else { set timer 1000 } after $timer send_sip \"$dstuser\" \"$user\" $aid $id \ $win \"$addr\" $port $ttl $transport } else { sip_connection_fail $id "No-one is listening to invitations sent to $sip_request_user($id)" } } return 0 } else { global sip_request_fd if {[sip_user_pending $user $id $aid $win]==0} { set sip_request_fd($id) [sip_send_tcp_request 0 $addr $port $msg] if {$sip_request_fd($id)>0} { set no_of_connections($id) 1 #no need for retransmissions, but arrange for the connection #to eventually timeout if no answer is received after 30000 sip_check_tcp_connection_status $user $id $aid $win } else { sip_connection_fail $id "No-one is listening to invitations sent to $sip_request_user($id)" sip_close_tcp_connection $id unset sip_request_fd($id) } } } } proc sip_check_tcp_connection_status {user id aid win} { global sip_request_fd sip_request_user #this is called to time out TCP connections to places where either #the TCP connection doesn't connect or we don't get a response back #after connection if {[sip_user_pending $user $id $aid $win]==1} { if {[info exists sip_request_user($id)]} { sip_connection_fail $id "No response from remote site while trying to contact $sip_request_user($id)" } if {[info exists sip_request_fd($id)]==1} { sip_close_tcp_connection $sip_request_fd($id) } } } proc sip_send_ack {fd dstuser origuser id cseq} { global youremail sdrversion sip_requests sip_request_status if {[lsearch $sip_requests $id]!=-1} { puts "sip_request_status($id)==$sip_request_status($id)" if {($sip_request_status($id)=="progressing") || \ ($sip_request_status($id)=="ringing") || \ ($sip_request_status($id)=="unknown") || \ ($sip_request_status($id)=="declined") || \ ($sip_request_status($id)=="connected")} { #the call is in progress or already connected set res [sip_parse_url $dstuser] set addr [lookup_host [lindex $res 2]] if {$addr=="0.0.0.0"} { msgpopup "Invalid Address" "The hostname $host is not known" return 0 } set maddr [lindex $res 6] set port [lindex $res 3] set ttl [lindex $res 5] set transport [lindex $res 4] if {$transport=="NONE"} { if {$fd==0} { set transport "UDP" } else { set transport "TCP" } } set msg "ACK $dstuser SIP/2.0" if {$maddr!=""} { if {$ttl==0} {set ttl 16} set msg "$msg\r\nVia: SIP/2.0/UDP $maddr;ttl=$ttl" } set msg "$msg\r\nVia: SIP/2.0/$transport [gethostaddr]" set msg "$msg\r\nCall-ID:$id" set msg "$msg\r\nCseq:[lindex $cseq 0] ACK" set msg "$msg\r\nFrom:sip:$youremail" set msg "$msg\r\nTo:$origuser" set msg "$msg\r\nUser-Agent:sdr/$sdrversion" set msg "$msg\r\nContent-length:0\r\n\r\n" if {$maddr!=""} {set addr $maddr} if {$transport=="UDP"} { sip_send_udp $addr $ttl $port $msg } else { sip_send_tcp_request $fd $addr $port $msg puts "about to close connection" sip_close_tcp_connection $id puts "connection closed" } } else { #the call is not in a useful state - either the far end #confused us, or we hung up. puts here1 sip_send_bye $fd $dstuser $origuser $id $cseq } } else { #we have no record of this call puts here2 sip_send_bye $fd $dstuser $origuser $id $cseq } } proc sip_send_bye {fd dstuser origuser id cseq} { global youremail sdrversion sip_requests sip_request_status if {[lsearch $sip_requests $id]!=-1} { #for some reason we're sending a bye but still have call state #clear it out #catch {unset sip_request_status($id)} } set res [sip_parse_url $dstuser] set addr [lookup_host [lindex $res 2]] if {$addr=="0.0.0.0"} { msgpopup "Invalid Address" "The hostname $host is not known" return 0 } set maddr [lindex $res 6] set port [lindex $res 3] set ttl [lindex $res 5] set transport [lindex $res 4] if {$transport=="NONE"} {set transport "UDP"} puts "sip_send_bye: $addr, $port, $ttl, $maddr" set msg "BYE $dstuser SIP/2.0" if {$maddr!=""} { if {$ttl==0} {set ttl 16} set msg "$msg\r\nVia: SIP/2.0/UDP $maddr;ttl=$ttl" } set msg "$msg\r\nVia: SIP/2.0/$transport [gethostaddr]" set msg "$msg\r\nCall-ID:$id" set msg "$msg\r\nCseq:[expr [lindex $cseq 0] + 1] BYE" set msg "$msg\r\nFrom:sip:$youremail" set msg "$msg\r\nTo:$origuser" set msg "$msg\r\nUser-Agent:sdr/$sdrversion" #XXX should a BYE include a body?? set msg "$msg\r\nContent-length:0\r\n\r\n" #puts "------\nSending to $addr:\n$msg\n" if {$transport=="UDP"} { if {$maddr!=""} {set addr $maddr} sip_send_udp $addr $ttl $port $msg } else { sip_send_tcp_request $fd $addr $port $msg } } proc sip_hang_up {id} { global sip_request_status set sip_request_status($id) hungup sip_clear_connection_ui $id } set sip_requests {} proc sip_user_pending {user id aid win} { global sip_request_status sip_requests sip_request_user sip_request_aid global sip_request_win # puts $id if {[lsearch $sip_requests $id]!=-1} { return 0 } foreach eid $sip_requests { if {$sip_request_user($eid)==$user} { if {($sip_request_status($eid)=="unknown")|| ($sip_request_status($eid)=="progressing")|| ($sip_request_status($eid)=="ringing")} { msgpopup "Call in progress" "You are already calling $user" return -1 } } } set sip_request_status($id) unknown set sip_request_user($id) $user set sip_request_aid($id) $aid set sip_request_win($id) $win set sip_requests "$sip_requests $id" set lid [join [split $id "."] "-"] # set f .inv.$aid.$lid set f $win.$lid frame $f pack $f -after $win.f label $f.l1 -text $user -width 20 pack $f.l1 -side left label $f.l2 -text "?" -width 10 pack $f.l2 -side left button $f.hangup -text "Hang up" -command "sip_hang_up $id" \ -borderwidth 1 -relief raised -highlightthickness 0 pack $f.hangup -side left return 0 } proc sip_session_status {id status} { global sip_request_status sip_requests sip_request_aid global sip_request_win if {[lsearch $sip_requests $id]==-1} { return 0 } set sip_request_status($id) [lindex $status 0] set lid [join [split $id "."] "-"] # set aid $sip_request_aid($id) set f $sip_request_win($id).$lid catch {$f.l2 configure -text $status} } set sip_invites {} proc sip_user_alert {fd msg} { global sip_invites sip_invite_status sip_invite_tag #puts " $fd TESTing $msg" set lines [split $msg "\n"] set cur-to [lindex [lindex $lines 0] 1] set request [lindex [lindex $lines 0] 0] set path "" set srcuser "" set dstuser "" set ct "" set cseq "" foreach line $lines { set line [string trim $line "\r"] if {$line==""} {break} set lparts [split $line ":"] switch [string toupper [lindex $lparts 0]] { CALL-ID { set id [string trim [join [lrange $lparts 1 end] ":"]] } FROM { set srcuser [string trim [join [lrange $lparts 1 end] ":"]] } TO { set dstuser [string trim [join [lrange $lparts 1 end] ":"]] } VIA { if {$path==""} { set path $line } else { set path "$path\r\n$line" } } CONTENT-TYPE { set ct [string trim [join [lrange $lparts 1 end] ":"]] } CSEQ { set cseq [string trim [join [lrange $lparts 1 end] ":"]] } } } debug "ct=$ct" #puts "request: >$request<" switch $request { "INVITE" { if {[string compare $ct "application/sdp"]!=0} { return 0 } foreach line $lines { set line [string trim $line "\r"] set lparts [split $line "="] switch [lindex $lparts 0] { s { set sname [join [lrange $lparts 1 end] "="] } } } # puts here if {[lsearch $sip_invites $id]==-1} { #it's a new invite set sip_invites "$sip_invites $id" #shouldn't really pass the SIP header to the SDP parser #but it doesn't break anything sip_inform_user $fd $id $srcuser $dstuser $path $sname \ $msg $cseq set sip_invite_status($id) ringing #this should be a UUID set sip_invite_tag($id) [gethostaddr].[gettimeofday] sip_ringing_user $fd $id $srcuser $dstuser $path $cseq } else { switch $sip_invite_status($id) { ringing { sip_ringing_user $fd $id $srcuser $dstuser $path $cseq } refused { set aid [parse_sdp $msg] sip_refuse_invite $aid } accepted { set aid [parse_sdp $msg] sip_accept_invite $aid } done { #fail silent? } } } } "BYE" { sip_handle_bye $fd $id $srcuser $dstuser $path $cseq } "CANCEL" { sip_handle_cancel $fd $id $srcuser $dstuser $path $cseq } "ACK" { sip_handle_ack $fd $id } default { sip_send_method_unsupported $fd $id $srcuser $dstuser \ $path $cseq $request } } } proc sip_handle_bye {fd id srcuser dstuser path cseq} { global sip_invites sip_invite_status sessdetails if {[lsearch $sip_invites $id]!=-1} { if {$sip_invite_status($id)=="accepted"} { #Ooops, the caller hung up after we sent our response #notify the user and stop sending retransmissions of #our 200 response set sip_invite_status($id) refused set aid $sessdetails($id,aid) popdown $aid msgpopup "Sorry" "Caller $sessdetails($aid,srcuser) has hung up the connection." sip_send_cancelled $fd $id $srcuser $dstuser $path $cseq } elseif {($sip_invite_status($id)=="ringing")} { #The caller hung up before we could get an answer from #the user #stop making all the noise and clear up set sip_invite_status($id) refused timeout_ringing $id sip_send_cancelled $fd $id $srcuser $dstuser $path $cseq } elseif {$sip_invite_status($id)=="connected"} { #We already got an ACK and now we get a BYE - we don't #perform this kind of call control in sdr. If we were a #telephone this would be OK and would terminate the call set sip_invite_status($id) refused sip_send_cancelled $fd $id $srcuser $dstuser $path $cseq return } else { #it's not clear what happened here, but set the call to #declined anyway set sip_invite_status($id) refused sip_send_cancelled $fd $id $srcuser $dstuser $path $cseq } } else { #a bye for a call we have no knowledge should result in #us returning "481 Invalid Call-ID" sip_send_invalid_callid $fd $id $srcuser $dstuser $path $cseq BYE } } proc sip_handle_cancel {fd id srcuser dstuser path cseq} { global sip_invites sip_invite_status sessdetails if {[lsearch $sip_invites $id]!=-1} { if {$sip_invite_status($id)=="accepted"} { #Ooops, the caller sent cancel after we sent our response #in this case we ignore cancel. The callee should send #us an ACK or a BYE to terminate our state. return } elseif {($sip_invite_status($id)=="ringing")} { #The caller sent cancel before we could get an answer from #the user #stop making all the noise and clear up set sip_invite_status($id) refused timeout_ringing $id sip_send_cancelled $fd $id $srcuser $dstuser $path $cseq } elseif {$sip_invite_status($id)=="connected"} { #We already got an ACK and now we get a CANCEL #this shouldn't happen, but ignore the CANCEL if it does return } else { #it's not clear what happened here, but set the call to #declined anyway set sip_invite_status($id) refused sip_send_cancelled $fd $id $srcuser $dstuser $path $cseq } } else { #a cancel for a call we have no knowledge of can be safely ignored } } proc sip_handle_ack {fd id} { #since we're optimists we assume that when we send a 200 response #the caller won't have hung up. All we do is stop sending #retransmissions of our 200 response global sip_invites sip_invite_status if {[lsearch $sip_invites $id]!=-1} { if {$sip_invite_status($id)=="accepted"} { set sip_invite_status($id) "connected" } if {$sip_invite_status($id)=="refused"} { set sip_invite_status($id) "done" } } } proc sip_inform_user {fd id srcuser dstuser path sname sdp cseq} { global ifstyle global sessdetails popup [set aid [parse_sdp $sdp]] $ifstyle(view) $srcuser set sessdetails($id,aid) $aid set sessdetails($aid,id) $id set sessdetails($aid,fd) $fd set sessdetails($aid,srcuser) $srcuser set sessdetails($aid,time) [gettimeofday] set sessdetails($aid,dstuser) $dstuser set sessdetails($aid,path) $path set sessdetails($aid,sdp) $sdp set sessdetails($aid,cseq) $cseq } proc sip_ringing_user {fd id srcuser dstuser path cseq} { set msg "SIP/2.0 180 Ringing" set msg "$msg\r\n$path" set msg "$msg\r\nCall-ID:$id" set msg "$msg\r\nFrom:$srcuser" set msg "$msg\r\nTo:$dstuser" if {$cseq!=""} { set msg "$msg\r\nCseq:$cseq" } set msg "$msg\r\nContact:sip:[getusername]@[gethostname]" set msg "$msg\r\nContent-length:0\r\n\r\n" sip_send_reply $fd $id $path $msg INVITE -1 start_ringing $id } proc sip_accept_invite {aid} { global sessdetails sip_invite_status ldata set fd $sessdetails($aid,fd) if {$sip_invite_status($sessdetails($aid,id))!="accepted"} { if {$ldata($aid,list)==""} { #no need to display it again id it's already displayed add_to_display_list $aid priv } } set sip_invite_status($sessdetails($aid,id)) accepted sip_send_accept_invite $fd \ $sessdetails($aid,id) \ $sessdetails($aid,srcuser) \ $sessdetails($aid,dstuser) \ $sessdetails($aid,path) \ $sessdetails($aid,sdp) \ $sessdetails($aid,cseq) stop_ringing } proc sip_refuse_invite {aid} { global sessdetails sip_invite_status set fd $sessdetails($aid,fd) set sip_invite_status($sessdetails($aid,id)) refused sip_send_refuse_invite $fd \ $sessdetails($aid,id) \ $sessdetails($aid,srcuser) \ $sessdetails($aid,dstuser) \ $sessdetails($aid,path) \ $sessdetails($aid,cseq) stop_ringing } proc sip_send_accept_invite {fd id srcuser dstuser path sdp cseq} { global sip_invites sip_invite_status sip_invite_responses global sip_invite_tag #keep resending the response until we get an ACK, BYE, or timeout set sip_invite_responses($id) 1 #puts "sip_send_accept_invite $sip_invite_status($id)" # if {[lsearch $sip_invites $id]>=0} { # if {$sip_invite_status($id)!="accepted"} { # catch {unset sip_invite_responses($id)} # return # } # #resend a maximum of 10 times according to spec # if {$sip_invite_responses($id)>10} { # unset sip_invite_responses($id) #we never got either an ACK or a NACK back in response #to our 200 response - strictly speaking this is a failure #and we should notify the user. # set sip_invite_status($id) failure # return # } # #resend every 2 seconds according to spec # incr sip_invite_responses($id) # after 2000 "sip_send_accept_invite $fd $id $srcuser $dstuser \ # \"$path\" \"$sdp\" {$cseq}" # } set tag ";tag=$sip_invite_tag($id)" puts "**tag: $tag" set msg "SIP/2.0 200 OK" set msg "$msg\r\n$path" set msg "$msg\r\nCall-ID:$id" set msg "$msg\r\nFrom:$srcuser" set msg "$msg\r\nTo:$dstuser$tag" if {$cseq!=""} { set msg "$msg\r\nCseq:$cseq" } set msg "$msg\r\nContact: sip:[getusername]@[gethostname]" #XXXX must send back the original request set msg "$msg\r\nContent-length:0\r\n\r\n" #puts "------\nSending response to [lrange $path end end]\n$msg\n" sip_send_reply $fd $id $path $msg INVITE 0 } proc sip_send_refuse_invite {fd id srcuser dstuser path cseq} { global sip_invite_tag set tag "" if {[info exists sip_invite_tag($id)]} { set tag ";tag=$sip_invite_tag($id)" } set msg "SIP/2.0 603 Decline" set msg "$msg\r\n$path" set msg "$msg\r\nCall-ID:$id" set msg "$msg\r\nFrom:$srcuser" set msg "$msg\r\nTo:$dstuser$tag" if {$cseq!=""} { set msg "$msg\r\nCseq:$cseq" } set msg "$msg\r\nContact: sip:[getusername]@[gethostname]" set msg "$msg\r\nContent-length:0\r\n\r\n" sip_send_reply $fd $id $path $msg INVITE 0 } proc sip_send_method_unsupported {fd id srcuser dstuser path cseq method} { global sip_invite_tag set tag "" if {[info exists sip_invite_tag($id)]} { set tag ";tag=$sip_invite_tag($id)" } set msg "SIP/2.0 501 Not Implemented" set msg "$msg\r\n$path" set msg "$msg\r\nCall-ID:$id" set msg "$msg\r\nFrom:$srcuser" set msg "$msg\r\nTo:$dstuser$tag" if {$cseq!=""} { set msg "$msg\r\nCseq:$cseq" } set msg "$msg\r\nContact: sip:[getusername]@[gethostname]" set msg "$msg\r\nContent-length:0\r\n\r\n" sip_send_reply $fd $id $path $msg $method 0 } proc sip_send_invalid_callid {fd id srcuser dstuser path cseq method} { global sip_invite_tag set tag "" if {[info exists sip_invite_tag($id)]} { set tag ";tag=$sip_invite_tag($id)" } set msg "SIP/2.0 481 Invalid Call-ID" set msg "$msg\r\nCall-ID:$id" set msg "$msg\r\nFrom:$srcuser" set msg "$msg\r\nTo:$dstuser$tag" if {$cseq!=""} { set msg "$msg\r\nCseq:$cseq" } set msg "$msg\r\nContact: sip:[getusername]@[gethostname]" set msg "$msg\r\nContent-length:0\r\n\r\n" sip_send_reply $fd $id $path $msg $method 0 } proc sip_send_unknown_user {fd id srcuser dstuser path cseq method} { global sip_invite_tag set tag "" if {[info exists sip_invite_tag($id)]} { set tag ";tag=$sip_invite_tag($id)" } set msg "SIP/2.0 404 Not Found" set msg "$msg\r\nCall-ID:$id" set msg "$msg\r\nFrom:$srcuser" set msg "$msg\r\nTo:$dstuser$tag" if {$cseq!=""} { set msg "$msg\r\nCseq:$cseq" } set msg "$msg\r\nContent-length:0\r\n\r\n" sip_send_reply $fd $id $path $msg $method 0 } proc sip_unknown_user_ack {callid} { #we got an ACK containing an unknown user. #either something bizarre happened, or we previously sent 404 Not Found #or something similar, so we need to stop resending this response. global sip_invite_status if {[info exists sip_invite_status($callid)]} { if {$sip_invite_status($callid)=="refused"} { #Ok, this makes sense - we had sent a response. set sip_invite_status($callid) "done" } else { puts "got an ACK for an unknown user when we're is $sip_invite_status($callid) state" } } } proc sip_send_cancelled {fd id srcuser dstuser path cseq} { global sip_invite_tag set tag "" if {[info exists sip_invite_tag($id)]} { set tag ";tag=$sip_invite_tag($id)" } set msg "SIP/2.0 200 Cancelled" set msg "$msg\r\nCall-ID:$id" set msg "$msg\r\nFrom:$srcuser" set msg "$msg\r\nTo:$dstuser$tag" if {$cseq!=""} { set msg "$msg\r\nCseq:$cseq" } set msg "$msg\r\nContact: sip:[getusername]@[gethostname]" set msg "$msg\r\nContent-length:0\r\n\r\n" sip_send_reply $fd $id $path $msg CANCEL 0 } proc sip_send_reply {fd callid path msg method counter} { global sip_invite_status set res [sip_parse_path $path] puts "$path ---> $res" set version [lindex $res 0] set transport [lindex $res 1] set host [lindex $res 2] set port [lindex $res 3] set ttl [lindex $res 4] if {$port==0} {set port 5060} set addr [lookup_host $host] puts "$host -> $addr" if {$addr=="0.0.0.0"} { msgpopup "Invalid Address" "The hostname $host is not known" return 0 } if {$transport=="UDP"} { if {$method=="INVITE"} { if {$counter==-1} { #it's a response we don't repeat sip_send_udp $addr $ttl $port $msg } elseif {$counter==0} { sip_send_udp $addr $ttl $port $msg after 2000 "sip_send_reply $fd \"$callid\" \"$path\" \ \"$msg\" $method 1" if {[info exists sip_invite_status($callid)]==0} { #we've no state for this reply - must be a failure #response - instatiate the state set sip_invite_status($callid) "refused" } } elseif {$counter<10} { #only keep retransmitting if we're in a retransmit state if {($sip_invite_status($callid)=="refused")|| ($sip_invite_status($callid)=="accepted")} { sip_send_udp $addr $ttl $port $msg after 2000 "sip_send_reply $fd \"$callid\" \"$path\" \ \"$msg\" $method [expr $counter + 1]" } } else { #we failed to get an ACK. if {$sip_invite_status($callid)=="accepted"} { set sip_invite_status($callid) failure } else { set sip_invite_status($callid) done } } } else { sip_send_udp $addr $ttl $port $msg } } else { sip_send_tcp_reply $fd $callid $addr $port $msg } } proc sip_success {fd msg pktsrc} { global sip_requests set lines [split $msg "\n"] #puts $msg set path "" set srcuser "" set dstuser "" set origuser "" set ct "" set cseq "" set method "" foreach line $lines { set line [string trim $line "\r"] if {$line==""} {break} set lparts [split $line ":"] switch [string toupper [lindex $lparts 0]] { CALL-ID { set id [string trim [join [lrange $lparts 1 end] ":"]] } CSEQ { set cseq [string trim [join [lrange $lparts 1 end] ":"]] set method [lindex $cseq 1] } FROM { set srcuser [string trim [join [lrange $lparts 1 end] ":"]] } TO { set origuser [string trim [join [lrange $lparts 1 end] ":"]] } VIA { if {$path==""} { set path $line } else { set path "$path\r\n$line" } } CONTENT-TYPE { set ct [string trim [join [lrange $lparts 1 end] ":"]] } CONTACT { set dstuser [string trim [join [lrange $lparts 1 end] ":"]] } } } if {[string compare $ct "application/sdp"]==0} { foreach line $lines { set line [string trim $line "\r"] set lparts [split $line "="] switch [lindex $lparts 0] { s { set sname [join [lrange $lparts 1 end] "="] } } } } if {$method == "INVITE"} { if {[lsearch $sip_requests $id]==-1} { sip_send_bye $fd $dstuser $origuser $id $cseq } else { sip_send_ack $fd $dstuser $origuser $id $cseq sip_connection_succeed $id "$dstuser accepts your invitation" if {$fd>0} { sip_close_tcp_connection $id } } } elseif {($method == "BYE")||($method == "CANCEL")} { #this is the response to our bye or cancel - now close the connection if {$fd>0} { sip_close_tcp_connection $id } } else { #don't know what happened here but we don't want to talk to #them again :-) if {$fd>0} { sip_close_tcp_connection $id } } } proc sip_status {fd msg pktsrc} { set smode [lindex $msg 1] set reason [lindex $msg 2] debug "sip_status: $smode" set lines [split $msg "\n"] set path "" set srcuser "" set dstuser "" set ct "" set ch "" foreach line $lines { set line [string trim $line "\r"] if {$line==""} {break} set lparts [split $line ":"] switch [string toupper [lindex $lparts 0]] { CALL-ID { set id [string trim [join [lrange $lparts 1 end] ":"]] } FROM { set srcuser [string trim [join [lrange $lparts 1 end] ":"]] } TO { set dstuser [string trim [join [lrange $lparts 1 end] ":"]] } VIA { if {$path==""} { set path $line } else { set path "$path\r\n$line" } } CONTENT-TYPE { set ct [string trim [join [lrange $lparts 1 end] ":"]] } CONTACT { set ch [string trim [join [lrange $lparts 1 end] ":"]] } } } set path [lindex [string trim [lindex [split $path ":"] 1]] 1] debug "smode: $smode id: $id path: >$path< me: >[gethostaddr]<" switch $smode { 100 { if {$path==[gethostaddr]} { #I sent this request sip_session_status $id progressing } } 180 { if {$path==[gethostaddr]} { #I sent this request sip_session_status $id ringing } } } } proc sip_failure {fd msg pktsrc} { global no_of_connections set smode [lindex $msg 1] set reason [lindex $msg 2] set lines [split $msg "\n"] set path "" set srcuser "" set dstuser "" set ct "" set cseq "" foreach line $lines { set line [string trim $line "\r"] if {$line==""} {break} set lparts [split $line ":"] switch [string toupper [lindex $lparts 0]] { CALL-ID { set id [string trim [join [lrange $lparts 1 end] ":"]] } CSEQ { set cseq [string trim [join [lrange $lparts 1 end] ":"]] set method [lindex $cseq 1] } FROM { set srcuser [string trim [join [lrange $lparts 1 end] ":"]] } TO { set dstuser [string trim [join [lrange $lparts 1 end] ":"]] } VIA { if {$path==""} { set path $line } else { set path "$path\r\n$line" } } CONTENT-TYPE { set ct [string trim [join [lrange $lparts 1 end] ":"]] } } } switch $smode { 400 { # Bad request sip_send_ack $fd $dstuser $dstuser $id $cseq if {$no_of_connections($id)==1} { sip_connection_fail $id "There was a internal SIP problem: code 400" } sip_cancel_connection $id $pktsrc } 401 { # Unauthorised sip_send_ack $fd $dstuser $dstuser $id $cseq if {$no_of_connections($id)==1} { sip_connection_fail $id "There was an authorization failure will contacting $dstuser" } sip_cancel_connection $id $pktsrc } 402 { # Payment required sip_send_ack $fd $dstuser $dstuser $id $cseq if {$no_of_connections($id)==1} { sip_connection_fail $id "$dstuser is requiring payment!" } sip_cancel_connection $id $pktsrc } 403 { # Forbidden sip_send_ack $fd $dstuser $dstuser $id $cseq if {$no_of_connections($id)==1} { sip_connection_fail $id "The remote server is refusing to connect your call" } sip_cancel_connection $id $pktsrc } 404 { #Not found sip_send_ack $fd $dstuser $dstuser $id $cseq if {$no_of_connections($id)==1} { sip_connection_fail $id "User $dstuser does not appear to exist" } sip_cancel_connection $id $pktsrc } 407 { #Method Not Allowed sip_send_ack $fd $dstuser $dstuser $id $cseq if {$no_of_connections($id)==1} { sip_connection_fail $id "There was a internal SIP problem: code 407" } sip_cancel_connection $id $pktsrc } 408 { #Request Timeout sip_send_ack $fd $dstuser $dstuser $id $cseq if {$no_of_connections($id)==1} { sip_connection_fail $id "There was a internal SIP problem: code 408" } sip_cancel_connection $id $pktsrc } 420 { #Bad extension sip_send_ack $fd $dstuser $dstuser $id $cseq if {$no_of_connections($id)==1} { sip_connection_fail $id "There was a internal SIP problem: code 420" } sip_cancel_connection $id $pktsrc } 480 { #temporarily unavailable sip_send_ack $fd $dstuser $dstuser $id $cseq if {$no_of_connections($id)==1} { sip_connection_fail $id "User $dstuser was unavailable" } sip_cancel_connection $id $pktsrc } 481 { #Invalid call ID sip_send_ack $fd $dstuser $dstuser $id $cseq if {$no_of_connections($id)==1} { sip_connection_fail $id "There was a internal SIP problem: code 481" } sip_cancel_connection $id $pktsrc } 481 { #Loop detected sip_send_ack $fd $dstuser $dstuser $id $cseq if {$no_of_connections($id)==1} { sip_connection_fail $id "There was a internal SIP problem: code 482" } sip_cancel_connection $id $pktsrc } 600 { # Busy sip_send_ack $fd $dstuser $dstuser $id $cseq sip_connection_fail $id "User $dstuser was busy" sip_cancel_connection $id all } 603 { # Decline sip_send_ack $fd $dstuser $dstuser $id $cseq sip_connection_fail $id "User $dstuser declined your call" sip_cancel_connection $id all } 604 { # Does not exist anywhere sip_send_ack $fd $dstuser $dstuser $id $cseq sip_connection_fail $id "User $dstuser aparently no longer exists!" sip_cancel_connection $id all } 606 { # Not acceptable sip_send_ack $fd $dstuser $dstuser $id $cseq sip_connection_fail $id "User $dstuser does not have the facilities to participate in the session you specified" sip_cancel_connection $id all } default { if {($smode>=400)&&($smode<600)} { sip_send_ack $fd $dstuser $dstuser $id $cseq if {$no_of_connections($id)==1} { sip_connection_fail $id \ "Failed to contact $dstuser (reason $smode)" } else { sip_cancel_connection $id $pktsrc } } else { sip_send_ack $fd $dstuser $dstuser $id $cseq sip_connection_fail $id \ "Failed to contact $dstuser (reason $smode)" sip_cancel_connection $id all } } } } proc sip_moved {fd msg pktsrc} { global no_of_connections sip_request_aid sip_request_win set smode [lindex $msg 1] set reason [lindex $msg 2] set lines [split $msg "\n"] set path "" set srcuser "" set dstuser "" set ct "" set contact "" set id "" foreach line $lines { set line [string trim $line "\r"] if {$line==""} {break} set lparts [split $line ":"] switch [string toupper [lindex $lparts 0]] { CALL-ID { set id [string trim [join [lrange $lparts 1 end] ":"]] } FROM { set srcuser [string trim [join [lrange $lparts 1 end] ":"]] } TO { set origuser [string trim [join [lrange $lparts 1 end] ":"]] } VIA { if {$path==""} { set path $line } else { set path "$path\r\n$line" } } CONTACT { set contact [string trim [join [lrange $lparts 1 end] ":"]] } CONTENT-TYPE { set ct [string trim [join [lrange $lparts 1 end] ":"]] } } } if {$id==""} { #got a redirect with no call ID - this is bogus #puts "Got a bogus response - no call-ID:\n$msg" return 0 } set aid $sip_request_aid($id) if {[string compare [string range $contact 0 3] "sip:"]==0} { #it's a SIP URL #trim the URL set contact [string range $contact 6 end] set param [string first ";" $contact] if {$param>=0} { #there was a parameter to the URL. #we don't understand parameters, so trim it off and continue #in the hope this is OK. set contact [string range $contact 0 [expr $param - 1]] } } if {[string first ":" $contact]>=0} { #it's some other URL if {$no_of_connections($id)==1} { sip_connection_fail $id "I got an alternative location I don't undertand: $contact." } sip_cancel_connection $id $pktsrc return } if {[string first "@" $contact]>=0} { set dstuser $contact } switch $smode { 301 { #moved permanently sip_session_status $id "progressing $contact" sip_cancel_connection $id $pktsrc send_sip $dstuser $dstuser $aid $id $sip_request_win($id) 0 0 0 NONE } 302 { #moved temporarily #puts "got a 302, $origuser->$dstuser" sip_session_status $id "progressing $contact" sip_cancel_connection $id $pktsrc send_sip $dstuser $origuser $aid $id $sip_request_win($id) 0 0 0 NONE } 380 { #alternative service #not yet supported if {$no_of_connections($id)==1} { sip_connection_fail $id "An alternative service was suggested by $dstuser but I don't support this yet." } sip_cancel_connection $id $pktsrc } } } proc sip_update_request_dst {mode aid id location} { } proc sip_connection_fail {id msg} { global sip_request_status sip_requests if {[lsearch $sip_requests $id]==-1} { # puts a return 0 } msgpopup "Connection attempt unsuccessful" $msg sip_clear_connection_ui $id set sip_request_status($id) declined } proc sip_clear_connection_ui {id} { global sip_request_win set lid [join [split $id "."] "-"] set f $sip_request_win($id).$lid catch {pack forget $f} } proc sip_connection_succeed {id msg} { global sip_request_status sip_requests sip_request_win sip_request_aid global ldata msgpopup "Connection attempt Successful" $msg set lid [join [split $id "."] "-"] set f $sip_request_win($id).$lid catch {$f.l2 configure -text "connected"} catch {pack forget $f.hangup} set sip_request_status($id) connected if {$ldata($sip_request_aid($id),list)==""} { #no need to add it to the display list if it's already displayed add_to_display_list $sip_request_aid($id) priv } } proc sip_cancel_connection {id hostaddr} { global sip_request_addrs puts "sip_cancel_connection $id $hostaddr" if {$hostaddr=="all"} { #need to cancel all requests made for this call-ID set sip_request_status($id) "declined" set list [array names sip_request_addrs] foreach item $list { set tmpid [lindex [split $item ","] 0] if {[string compare $tmpid $id]==0} { set sip_request_addrs($item) "failed" } } } else { set list [array names sip_request_addrs] foreach item $list { #puts "addrs: $item $sip_request_addrs($item)" } set sip_request_addrs($id,$hostaddr) "failed" } } proc escape_quotes {msg} { return [join [split $msg "\""] "\\\""] } proc start_ringing {id} { global ringing_bell bells if {$ringing_bell==1} { after cancel $bells(0) set bells(0) [after 15000 timeout_ringing $id] return 0 } set ringing_bell 1 phone_ringing #the choice of timing the call out after 15 seconds is somewhat #arbitrary. If the sender conforms to the spec, they should resend #the request every 5 seconds after they receive a RINGING response, #so this allows for reasonable loss rates and yet doesn't let the #ringing continue too long when the caller may have hung up and the #BYE got lost. set bells(0) [after 15000 timeout_ringing $id] } proc stop_ringing {} { global ringing_bell bells after cancel $bells(0) set ringing_bell 0 } proc timeout_ringing {id} { global sessdetails set aid $sessdetails($id,aid) popdown $aid add_to_call_list $aid stop_ringing } set ringing_bell 0 proc phone_ringing {} { global ringing_bell bells catch {after cancel $bells(3)} if {$ringing_bell==0} { catch { after cancel $bells(1) after cancel $bells(2) } return 0 } bell set bells(1) [after 200 bell] set bells(2) [after 400 bell] set bells(3) [after 1500 phone_ringing] } set sip_call_list {} proc add_to_call_list {aid} { global sip_call_list sessdetails if {$sip_call_list == {} } { toplevel .calls wm title .calls "Incoming Calls" frame .calls.f -borderwidth 2 -relief groove pack .calls.f -side top -expand true -fill both label .calls.f.l -text "While you were out..." pack .calls.f.l -side top message .calls.f.m -aspect 500 -text "You received incoming calls which were not answered from the following people:" pack .calls.f.m -side top frame .calls.f.f -relief groove -borderwidth 2 pack .calls.f.f -side top -fill both -expand true frame .calls.f.f.from pack .calls.f.f.from -side left -fill both -expand true label .calls.f.f.from.l -text "Caller" pack .calls.f.f.from.l -side top frame .calls.f.f.purpose pack .calls.f.f.purpose -side left -fill both -expand true label .calls.f.f.purpose.l -text "Purpose" pack .calls.f.f.purpose.l -side top frame .calls.f.f.time pack .calls.f.f.time -side left -fill both -expand true label .calls.f.f.time.l -text "Time" pack .calls.f.f.time.l -side top frame .calls.f.cp -borderwidth 2 -relief groove pack .calls.f.cp -expand true -fill x -side top button .calls.f.cp.cancel -text "Dismiss" -command { set sip_call_list {} destroy .calls } pack .calls.f.cp.cancel -side right -fill x -expand true } if {[winfo exists .calls.f.f.from.l$aid]==0} { label .calls.f.f.from.l$aid -text $sessdetails($aid,srcuser) pack .calls.f.f.from.l$aid -side bottom label .calls.f.f.purpose.l$aid -text "unknown" pack .calls.f.f.purpose.l$aid -side bottom label .calls.f.f.time.l$aid -text \ [clock format $sessdetails($aid,time) -format "%H:%M %a %d %b"] pack .calls.f.f.time.l$aid -side bottom lappend sip_call_list $aid } else { #the person recalled with the same call id. Simply replace the #previous information... .calls.f.f.from.l$aid configure -text $sessdetails($aid,srcuser) .calls.f.f.time.l$aid configure -text \ [clock format $sessdetails($aid,time) -format "%H:%M %a %d %b"] } } proc enter_new_address {menu entry} { global address_book ab catch {destroy .ab} toplevel .ab posn_win .ab wm title .ab "Address Book" frame .ab.f -borderwidth 2 -relief groove pack .ab.f -side top frame .ab.f.f1 pack .ab.f.f1 -side top label .ab.f.f1.l -text "Add an entry to your address book" pack .ab.f.f1.l -side left frame .ab.f.f2 -relief groove -borderwidth 2 pack .ab.f.f2 -side top -fill both -expand true -padx 10 frame .ab.f.f2.f1 pack .ab.f.f2.f1 -side left label .ab.f.f2.f1.l -text "Name:" pack .ab.f.f2.f1.l -side top -anchor w entry .ab.f.f2.f1.e -width 40 -relief sunken -borderwidth 1 \ -bg [option get . entryBackground Sdr] \ -textvariable ab(name) pack .ab.f.f2.f1.e -side top -anchor w frame .ab.f.f4 -relief groove -borderwidth 2 message .ab.f.f4.m -aspect 600 -text "Enter either the person's username and hostname, or a SIP URL for them." pack .ab.f.f4.m -side top frame .ab.f.f4.f4 frame .ab.f.f4.f4.f1 pack .ab.f.f4.f4.f1 -side left label .ab.f.f4.f4.f1.l -text "Person's Username:" pack .ab.f.f4.f4.f1.l -side top -anchor w entry .ab.f.f4.f4.f1.e -width 20 -relief sunken -borderwidth 1 \ -bg [option get . entryBackground Sdr] \ -textvariable ab(username) trace variable ab(username) w "ab_activity" pack .ab.f.f4.f4.f1.e -side top -anchor w frame .ab.f.f4.f4.f2 pack .ab.f.f4.f4.f2 -side left label .ab.f.f4.f4.f2.l -text "Their computer hostname:" pack .ab.f.f4.f4.f2.l -side top -anchor w entry .ab.f.f4.f4.f2.e -width 30 -relief sunken -borderwidth 1 \ -bg [option get . entryBackground Sdr] \ -textvariable ab(hostname) trace variable ab(hostname) w "ab_activity" pack .ab.f.f4.f4.f2.e -side top -anchor w pack .ab.f.f4.f4 -side top frame .ab.f.f4.f5 frame .ab.f.f4.f5.f1 pack .ab.f.f4.f5.f1 -side left label .ab.f.f4.f5.f1.l -text "SIP URL for person:" pack .ab.f.f4.f5.f1.l -side top -anchor w entry .ab.f.f4.f5.f1.e -width 50 -relief sunken -borderwidth 1 \ -bg [option get . entryBackground Sdr] \ -textvariable ab(url) trace variable ab(url) w "ab_activity" pack .ab.f.f4.f5.f1.e -side top -anchor w .ab.f.f4.f5.f1.e insert 0 "sip:" pack .ab.f.f4.f5 -side top pack .ab.f.f4 -side top -padx 10 -pady 10 -fill both -expand true frame .ab.f.f3 pack .ab.f.f3 -side top -fill x -expand true button .ab.f.f3.ok -text "Store Entry" -command "add_address_entry $menu $entry" pack .ab.f.f3.ok -side left -fill x -expand true button .ab.f.f3.cancel -text "Cancel" -command "destroy .ab" pack .ab.f.f3.cancel -side left -fill x -expand true set ab(first) "" } proc ab_activity args { global ab puts "$args" set type [lindex $args 1] puts "var: $ab($type), first: $ab(first)" if {$type=="url"} { if {([string length $ab(url)]>4)&&($ab(first)=="")} { if {$ab(first)==""} {set ab(first) url} .ab.f.f4.f4.f1.e configure -state disabled -relief flat \ -background [option get . background Sdr] .ab.f.f4.f4.f2.e configure -state disabled -relief flat \ -background [option get . background Sdr] } elseif {([string length $ab(url)]<=4)&&($ab(first)=="url")} { .ab.f.f4.f4.f1.e configure -state normal -relief sunken \ -background [option get . entryBackground Sdr] .ab.f.f4.f4.f2.e configure -state normal -relief sunken \ -background [option get . entryBackground Sdr] set ab(first) "" } } elseif {$type=="username"} { if {(($ab(username)!="")||($ab(hostname)!=""))&&($ab(first)!="url")} { if {$ab(first)==""} {set ab(first) username} .ab.f.f4.f5.f1.e configure -state normal .ab.f.f4.f5.f1.e delete 0 end .ab.f.f4.f5.f1.e insert 0 "sip:$ab(username)@$ab(hostname)" .ab.f.f4.f5.f1.e configure -state disabled \ -background [option get . background Sdr] -relief flat } elseif {($ab(username)=="")&&($ab(hostname)=="")} { .ab.f.f4.f5.f1.e configure \ -background [option get . entryBackground Sdr] \ -relief sunken -state normal .ab.f.f4.f5.f1.e delete 0 end .ab.f.f4.f5.f1.e insert 0 "sip:" set ab(first) "" } } elseif {$type=="hostname"} { if {(($ab(username)!="")||($ab(hostname)!=""))&&($ab(first)!="url")} { if {$ab(first)==""} {set ab(first) hostname} .ab.f.f4.f5.f1.e configure -state normal .ab.f.f4.f5.f1.e delete 0 end .ab.f.f4.f5.f1.e insert 0 "sip:$ab(username)@$ab(hostname)" .ab.f.f4.f5.f1.e configure -state disabled \ -background [option get . background Sdr] -relief flat } elseif {($ab(username)=="")&&($ab(hostname)=="")} { .ab.f.f4.f5.f1.e configure \ -background [option get . entryBackground Sdr] \ -relief sunken -state normal .ab.f.f4.f5.f1.e delete 0 end .ab.f.f4.f5.f1.e insert 0 "sip:" set ab(first) "" } } } proc embedd_enter_new_address {origwin win after mode} { global tmp_address_book ab_user active_address_book $origwin add frame $win.f -borderwidth 2 -relief groove pack $win.f -side top -after $after -fill x -expand true frame $win.f.f2 pack $win.f.f2 -side top frame $win.f.f2.cp pack $win.f.f2.cp -side right button $win.f.f2.cp.ok -highlightthickness 0 pack $win.f.f2.cp.ok -side top -fill x -expand true button $win.f.f2.cp.cancel -text "Cancel" \ -highlightthickness 0 \ -command "destroy $win.f;active_address_book $origwin unselected" pack $win.f.f2.cp.cancel -side top -fill x -expand true frame $win.f.f2.f1 pack $win.f.f2.f1 -side left -fill x -expand true label $win.f.f2.f1.l -text "Name:" -anchor nw pack $win.f.f2.f1.l -side top -anchor w -fill x -expand true entry $win.f.f2.f1.e -width 20 -relief sunken -borderwidth 1 \ -bg [option get . entryBackground Sdr] pack $win.f.f2.f1.e -side top -anchor w -fill x -expand true frame $win.f.f2.f2 pack $win.f.f2.f2 -side left -fill x -expand true label $win.f.f2.f2.l -text "Address:" -anchor nw pack $win.f.f2.f2.l -side top -anchor w -fill x -expand true entry $win.f.f2.f2.e -width 30 -relief sunken -borderwidth 1 \ -bg [option get . entryBackground Sdr] pack $win.f.f2.f2.e -side top -anchor w -fill x -expand true if {$mode=="add"} { $win.f.f2.cp.ok configure -text "Store Entry" -command \ "embedd_add_address_entry $win.f.f2.f1.e $win.f.f2.f2.e $win.f $origwin" } else { $win.f.f2.cp.ok configure -text "Modify Entry" -command \ "delete_address_entry \"$ab_user\";\ embedd_add_address_entry $win.f.f2.f1.e $win.f.f2.f2.e $win.f $origwin" $win.f.f2.f1.e insert 0 $ab_user $win.f.f2.f2.e insert 0 $tmp_address_book($ab_user) } } proc add_address_entry {menu entry button} { global address_book ab if {$ab(name)==""} { errorpopup "No name entered" "You must enter a name to add to your address book" return -1 } if {([string length $ab(url)] <=4) || ([string first "@" $ab(url)]<0)} { if {($ab(username)!="")||($ab(hostname)!="")} { errorpopup "Invalid address entered" "You must enter both a username and hostname" } else { errorpopup "Invalid URL entered" "You must enter a SIP URL in one of the following forms: \"sip:@\", \"sip:@:\", or \"sip:@;maddr=;ttl=\"" } return -1 } clear_address_book $menu set address_book($ab(name)) $ab(url) make_address_book $menu $entry $button save_prefs catch {destroy .ab} foreach var [array names ab] { unset ab($var) } return 0 } proc embedd_add_address_entry {uwin awin destroy origwin} { global tmp_address_book set name [$uwin get] if {$name==""} { errorpopup "No name entered" "You must enter a name to add to your address book" return -1 } set address [$awin get] if {($address == "") || ([string first "@" $address]<0)} { errorpopup "Invalid address entered" "You must enter an address for $name. his should be in the form \"username@hostname\"" return -1 } active_address_book $origwin unselected set tmp_address_book($name) $address embedd_redisplay_address_book $origwin save_prefs catch {destroy $destroy} return 0 } proc delete_address_entry {user} { global tmp_address_book if {([info exists tmp_address_book])&&($user!="")} { unset tmp_address_book($user) } } proc make_address_book {menu entry button} { global address_book if {$menu!="0"} { if {[info exists address_book]} { foreach user [array names address_book] { $menu add command -label $user -command \ "insert_invite_addr $entry $button \"$address_book($user)\"" } } else { $menu add command -label \ "No entries in address book" -state disabled } $menu add separator $menu add command -label "Add new entry" -command \ "enter_new_address $menu $entry" } } proc clear_address_book {menu} { if {$menu!="0"} { $menu delete 0 end } } proc insert_invite_addr {entry button address} { $entry delete 0 end $entry insert 0 $address check_sip_url $entry $button } proc save_address_book {file} { global address_book if {[info exists address_book]} { foreach user [array names address_book] { regsub -all " " $user "\\ " tmpuser puts $file "set address_book($tmpuser) \"$address_book($user)\"" } } } proc address_book_copyin {} { global address_book tmp_address_book if {[info exists address_book]} { foreach name [array names address_book] { set tmp_address_book($name) $address_book($name) } } } proc address_book_copyout {} { global address_book tmp_address_book if {[info exists address_book]} { foreach name [array names address_book] { unset address_book($name) } } if {[info exists tmp_address_book]} { foreach name [array names tmp_address_book] { set address_book($name) $tmp_address_book($name) unset tmp_address_book($name) } } } proc select_address_book {win width height} { global tmp_address_book frame $win -relief raised -borderwidth 3 frame $win.setw -borderwidth 0 -height 1 -width $width pack $win.setw -side top frame $win.f -borderwidth 2 pack $win.f -side top frame $win.f.f1 pack $win.f.f1 -side top label $win.f.f1.l -text "Address Book for Session Invitation" pack $win.f.f1.l -side left frame $win.f.f2 pack $win.f.f2 -side top frame $win.f.f2.cp pack $win.f.f2.cp -side left -anchor nw button $win.f.f2.cp.add -text "Add Entry" \ -highlightthickness 0 \ -command "embedd_enter_new_address $win $win.f $win.f.f1 add" pack $win.f.f2.cp.add -side top -fill x -expand true button $win.f.f2.cp.edit -text "Edit" \ -highlightthickness 0 -state disabled \ -command "embedd_enter_new_address $win $win.f $win.f.f1 modify" pack $win.f.f2.cp.edit -side top -fill x -expand true button $win.f.f2.cp.delete -text "Delete" \ -highlightthickness 0 -state disabled \ -command "delete_address_entry \[set ab_user\];\ embedd_redisplay_address_book $win" pack $win.f.f2.cp.delete -side top -fill x -expand true listbox $win.f.f2.l -width 20 -height 12 -yscroll "set_ab_lbscroll $win" pack $win.f.f2.l -side left bind $win.f.f2.l <1> [format { tkListboxBeginSelect %%W [%%W index @%%x,%%y] address_book_select %s user } $win] listbox $win.f.f2.r -width 30 -height 12 -yscroll "set_ab_lbscroll $win" pack $win.f.f2.r -side left bind $win.f.f2.r <1> [format { tkListboxBeginSelect %%W [%%W index @%%x,%%y] address_book_select %s address } $win] scrollbar $win.f.f2.sb -command "set_ab_scroll $win" \ -background [resource scrollbarForeground] \ -troughcolor [resource scrollbarBackground] \ -borderwidth 1 -relief flat \ -highlightthickness 0 pack $win.f.f2.sb -side left -fill y -expand true if {[info exists tmp_address_book]} { foreach user [array names tmp_address_book] { $win.f.f2.l insert end $user $win.f.f2.r insert end $tmp_address_book($user) } } #provide additional vertical padding in the canvas frame $win.f2 -borderwidth 0 -relief flat -width 1 -height \ [expr $height - [winfo reqheight $win]] pack $win.f2 -side top } proc set_ab_scroll {win args} { eval $win.f.f2.r yview $args eval $win.f.f2.l yview $args } proc set_ab_lbscroll {win args} { eval $win.f.f2.l yview moveto [lindex $args 0] eval $win.f.f2.r yview moveto [lindex $args 0] eval $win.f.f2.sb set $args } proc embedd_redisplay_address_book {win} { global tmp_address_book $win.f.f2.l delete 0 end $win.f.f2.r delete 0 end if {[info exists tmp_address_book]} { foreach user [array names tmp_address_book] { $win.f.f2.l insert end $user $win.f.f2.r insert end $tmp_address_book($user) } } } proc address_book_select {win which} { global tmp_address_book ab_user set ab_user "" if {[info exists tmp_address_book]} { switch $which { user { set ab_user [selection get] set address $tmp_address_book($ab_user) } address { set address [selection get] foreach u [array names tmp_address_book] { if {[string compare $tmp_address_book($u) $address]==0} { set ab_user $u break } } } } if {$ab_user!=""} { active_address_book $win selected } else { active_address_book $win unselected } } } proc active_address_book {win mode} { switch $mode { add { selection clear $win.f.f2.cp.add configure -state disabled $win.f.f2.cp.edit configure -state disabled $win.f.f2.cp.delete configure -state disabled $win.f.f2.l configure -fg \ [option get . disabledForeground Sdr] $win.f.f2.r configure -fg \ [option get . disabledForeground Sdr] } edit { $win.f.f2.cp.add configure -state disabled $win.f.f2.cp.edit configure -state disabled $win.f.f2.cp.delete configure -state disabled } selected { $win.f.f2.cp.add configure -state normal $win.f.f2.cp.edit configure -state normal $win.f.f2.cp.delete configure -state normal $win.f.f2.l configure -fg \ [option get . foreground Sdr] $win.f.f2.r configure -fg \ [option get . foreground Sdr] } unselected { selection clear $win.f.f2.cp.add configure -state normal $win.f.f2.cp.edit configure -state disabled $win.f.f2.cp.delete configure -state disabled $win.f.f2.l configure -fg \ [option get . foreground Sdr] $win.f.f2.r configure -fg \ [option get . foreground Sdr] } } } #set invite_ctr 0 proc parse_sdp {msg} { global ldata debug "*******************************" set lines [split $msg "\n"] foreach line $lines { set tag [lindex [split $line "="] 0] set value [join [lrange [split $line "="] 1 end] "="] switch $tag { v { if {$value!="0"} {debug "new announcement";return 0} } o { set str [lindex $value 0][lindex $value 1][lindex $value 5] set aid [get_aid $str] set ldata($aid,creator) [lindex $value 0] set ldata($aid,modtime) [lindex $value 2] set ldata($aid,createtime) [lindex $value 1] set ldata($aid,createaddr) [lindex $value 5] set ldata($aid,phonelist) "" set ldata($aid,emaillist) "" set ldata($aid,vars) "" set ldata($aid,no_of_times) -1 set ldata($aid,uri) 0 set ldata($aid,multicast) 0 set ldata($aid,key) "" if {![info exists ldata($aid,trust)]} { set ldata($aid,trust) "sip" } if {![info exists ldata($aid,sap_addr)]} { #which SAP address and port did this come from? - none! set ldata($aid,sap_addr) "" set ldata($aid,sap_port) "" } if {![info exists ldata($aid,started)]} { #have the media tools been started? - no set ldata($aid,started) 0 } if {![info exists ldata($aid,list)]} { #which display list is it on - none yet set ldata($aid,list) "" } set mn -1 if {![info exists ldata($aid,heardfrom)]} { #only set these if we didn't already know about it set ldata($aid,source) $ldata($aid,createaddr) set ldata($aid,heardfrom) "session invitation" set ldata($aid,theard) [fixtime [gettime [gettimeofday]]] set ldata($aid,method) invite set ldata($aid,lastheard) [gettimeofday] } } s { set ldata($aid,session) $value } i { set ldata($aid,desc) $value } p { if {$ldata($aid,phonelist)==""} { set ldata($aid,phonelist) "{$value}" } else { set ldata($aid,phonelist) "$ldata($aid,phonelist) {$value}" } } e { if {$ldata($aid,emaillist)==""} { set ldata($aid,emaillist) "{$value}" } else { set ldata($aid,emaillist) "$ldata($aid,emaillist) {$value}" } } u { set ldata($aid,uri) $value } c { debug $value if {([lindex $value 0]!="IN")&&([lindex $value 1]!="IP4")} { debug "Unknown address type" return 0; } set tmp [split [lindex $value 2] "/"] if {$mn==-1} { set ldata($aid,multicast) [lindex $tmp 0] set ldata($aid,ttl) [lindex $tmp 1] } else { set ldata($aid,$mn,addr) [lindex $tmp 0] set ldata($aid,$mn,ttl) [lindex $tmp 1] if {[llength $tmp] > 2} { set ldata($aid,$mn,layers) [lindex $tmp 2] } else { set ldata($aid,$mn,layers) 1 } } } t { incr ldata($aid,no_of_times) set t $ldata($aid,no_of_times) if {$t==0} { set ldata($aid,starttime) [ntp_to_unix [lindex $value 0]] set ldata($aid,endtime) [ntp_to_unix [lindex $value 1]] } else { if {[lindex $value 0]<$ldata($aid,starttime)} { set ldata($aid,starttime) [ntp_to_unix [lindex $value 0]] } if {[lindex $value 1]>$ldata($aid,endtime)} { set ldata($aid,endtime) [ntp_to_unix [lindex $value 1]] } } set ldata($aid,starttime,$t) [ntp_to_unix [lindex $value 0]] set ldata($aid,endtime,$t) [ntp_to_unix [lindex $value 1]] set ldata($aid,tfrom,$t) start set ldata($aid,tto,$t) end set ldata($aid,time$t,no_of_rpts) 0 } a { if {$mn==-1} { if {$ldata($aid,vars)==""} { set ldata($aid,vars) $value } else { set ldata($aid,vars) "$ldata($aid,vars)\n$value" } switch [lindex [split $value ":"] 0] { tool { set ldata($aid,tool) [lindex [split $value ":"] 1] } type { set ldata($aid,type) [lindex [split $value ":"] 1] } } } else { if {$ldata($aid,$mn,vars)==""} { set ldata($aid,$mn,vars) $value } else { set ldata($aid,$mn,vars) "$ldata($aid,$mn,vars)\n$value" } } } k { if {$mn!=-1} { if { [lindex [split $value ":"] 0] == "clear" } { set ldata($aid,$mn,mediakey) [lindex [split $value ":"] 1] } } } m { incr mn catch { #there may or may not have already been a "c=" field set ldata($aid,$mn,addr) $ldata($aid,multicast) set ldata($aid,$mn,ttl) $ldata($aid,ttl) } set ldata($aid,$mn,vars) "" set ldata($aid,$mn,media) [lindex $value 0] set ldata($aid,$mn,port) [lindex $value 1] set ldata($aid,$mn,proto) [lindex $value 2] set ldata($aid,$mn,fmt) [lrange $value 3 end] } } } set ldata($aid,medianum) [expr $mn+1] if {$ldata($aid,starttime)==0} { set ldata($aid,tfrom) 0 } else { set ldata($aid,tfrom) [fixtime [gettime \ [ntp_to_unix $ldata($aid,starttime)]]] } if {$ldata($aid,endtime)==0} { set ldata($aid,tto) 0 } else { set ldata($aid,tto) [fixtime [gettime \ [ntp_to_unix $ldata($aid,endtime)]]] } if {$ldata($aid,multicast)==0} { set ldata($aid,multicast) $ldata($aid,0,addr) set ldata($aid,ttl) $ldata($aid,0,ttl) } incr ldata($aid,no_of_times) debug $aid debug "[gettimeofday] $ldata($aid,starttime) $ldata($aid,endtime)" debug end return $aid } proc fixtime {gt} { set y [lindex $gt 0] set m [lindex $gt 1] set e [lindex $gt 2] set H [lindex $gt 3] set M [lindex $gt 4] set w [lindex $gt 5] set B [lindex $gt 6] set a [lindex $gt 7] set A [lindex $gt 8] set Z [lindex $gt 9] return "$e $B $y $H:$M $Z" } proc get_aid {str} { set aid 0 set len [expr [string length $str]/4] for {set i 0} {$i <= $len} {incr i} { set int 0 for {set j [expr $i*4]} {$j<[expr ($i+1)*4]} {incr j 4} { set a 0;set b 0;set c 0;set d 0 scan [string range $str $j [expr $j+3]] "%c%c%c%c" a b c d set int [expr (((((($a*256)+$b)*256)+$c)*256)+$d)] # set int [expr (((((($d*256)+$c)*256)+$b)*256)+$a)] set aid [expr (($aid<<1)|(($aid>>31)&1))^$int] } } set aid [format "%x" $aid] return $aid } #sdr.tcl #Copyright University College London 1995, 1996 #Copyright USC/ISI, 1997, 1996, 1998 #see ui_fns.c for information on usage and redistribution of this file #and for a DISCLAIMER OF ALL WARRANTIES. set initWait 400 set last_widget foo set showwhich all set yourname "" set yourphone "" set youremail "" set youralias "" set sip_server_url "sip:north.east.isi.edu" set keylist "" set lang C catch {set lang $env(LANG)} proc debug {str} { global debug1 if {$debug1} { puts $str } } proc putlogfile {text} { global logfile # puts "In putlogfile - logfile = $logfile" # set out [open $logfile a] # puts $out "$text" # close $out # change to just the followign if on unix and want all output to screen # puts "$text" } #set langtab [open "/tmp/langtab" "w"] proc tt {english} { global langtab trdone global lang trs if {$lang=="C"} { set tmp "" catch {set tmp $trdone($english)} if {$tmp == ""} { regsub -all "\"" $english "\\\"" tmp # puts $langtab "t \"$tmp\" XX \"$tmp\"" } return "$english" } else { set res "$english" catch {set res "$trs($lang,$english)"} return "$res" } } proc t {english lang other} { global trs # putlogfile "tranlating $english to $other in $lang" set trs($lang,$english) $other } t "New" de "Neu" t "New" fr "Neuf" t "Heard from" fr "Ecoutee de" t "Session Name:" fr "Nom de Session:" catch {source [resource sdrHome]/$lang} proc gettime {sec} { set res [clock format $sec -format {%Y %m %d %H %M %w %B %a %A}] #do TZ separately because of a bug in IRIX which returns TZ with an #unmatched quote preceding it set tz [clock format $sec -format {%Z}] lappend res $tz return $res } proc gettimeofday {} { clock seconds } proc gettimenow {} { gettime [clock seconds] } proc getreadabletime {} { return [clock format [clock seconds] -format {%H:%M, %d/%m/%y}] } set sdrversion "v2.5.8" set titlestr "Multicast Session Directory $sdrversion" proc initialise_resources {} { global gui if {$gui=="NO_GUI"} { return } #Tk4.0 standard bg option add *background gray85 #Use same colours as vat option add *foreground black option add *activeBackground gray95 option add *activeForeground black option add *hotForeground blue option add *activehotForeground red option add *selectBackground gray95 option add *scrollbarBackground gray50 option add *scrollbarForeground gray80 option add *scrollbarActiveForeground gray95 option add *canvasBackground gray95 option add *prefsBackground gray50 option add *balloonBg gray50 option add *balloonFg white #test option add *disabledBackground gray80 option add *disabledForeground gray50 option add *entryBackground lightsteelblue if { [winfo depth .] == 1 } { # make mono look better option add *background white option add *selectBackground black option add *selectForeground white option add *activeBackground white option add *activeForeground black option add *activehotForeground black option add *balloonBg black option add *balloonFg white option add *scrollbarBackground white option add *scrollbarForeground black option add *scrollbarActiveForeground black option add *entryBackground white } option add *infoFont -*-helvetica-medium-r-normal--*-100-*-*-*-*-iso8859-1 option add *headerFont -*-helvetica-bold-r-normal--*-140-*-*-*-*-iso8859-1 option add *largeFont -*-helvetica-bold-r-normal--*-240-*-*-*-*-iso8859-1 option add *mediumFont -*-helvetica-medium-r-normal--*-120-*-*-*-*-iso8859-1 option add *font -*-helvetica-medium-r-normal--*-120-*-*-*-*-iso8859-1 option add *italfont -*-helvetica-bold-o-normal--*-120-*-*-*-*-iso8859-1 set tmp 0 catch {set tmp [label .test -font [option get . font Sdr]];destroy .test} if {$tmp==0} { option add *font 8x13 100 option add *infoFont 6x9 100 option add *largeFont 9x15bold 100 option add *headerFont 9x15 100 option add *mediumFont 8x13 100 option add *italfont 8x13bold 100 } #fix odd little bug in tk4.0 Entry deletion bind Entry { if [%W selection present] { %W delete sel.first sel.last } else { set tk_fix(ix) [expr [%W index insert] -1] if {$tk_fix(ix)>=0} { %W delete $tk_fix(ix) } } } bind Entry { if [%W selection present] { %W delete sel.first sel.last } else { set tk_fix(ix) [expr [%W index insert] -1] if {$tk_fix(ix)>=0} { %W delete $tk_fix(ix) } } } bind Text { if {[%W tag nextrange sel 1.0 end] != ""} { %W delete sel.first sel.last } else { %W delete insert-1c %W see insert } } bind Text { if {[%W tag nextrange sel 1.0 end] != ""} { %W delete sel.first sel.last } elseif [%W compare insert != 1.0] { %W delete insert-1c %W see insert } } bind Text { #nothing } } proc scroll_to_session {key list} { global ldata items ix sessbox if {[string length $key] != 1} { return } set key [string tolower $key] for {set i 0} {$i < $items($list)} {incr i} { if {[string tolower [string index $ldata($ix($list,$i),session) 0]] >= $key} { break } } $sessbox($list) see $i.0 } proc build_interface {first} { global tcl_platform ifstyle gui sessbox global logfile if {$gui=="NO_GUI"} { return } log "Sdr started by [getusername] at [getreadabletime]" set lb $ifstyle(labels) global titlestr wm title . "sdr:[getemailaddress]" wm iconbitmap . sdr if {$first=="first"} { set tmpfile [clock format [clock seconds] -format {%H%M%S}] set logfile "[glob -nocomplain [resource sdrHome]]/log$tmpfile.txt" # puts "debug - logfile will be $logfile" set startlogtime "[clock format [clock seconds]]" putlogfile "logfile started at $startlogtime" frame .f1 -relief groove -borderwidth 2 # label .f1.l2 -bitmap ucl # pack .f1.l2 -side left -fill x label .f1.l -text $titlestr -width 32 pack .f1.l -side left -fill x frame .f2 -relief sunken -borderwidth 2 label .f2.l -text "Public Sessions" -font [option get . infoFont Sdr] \ -relief raised -borderwidth 1 pack .f2.l -side top -fill x text .f2.lb -width 20 -height 15 -yscroll ".f2.sb set" \ -relief flat -wrap none\ -selectforeground [resource activeForeground] \ -selectbackground [resource activeBackground] \ -highlightthickness 0 init_session_list norm .f2.lb scrollbar .f2.sb -command ".f2.lb yview" \ -background [resource scrollbarForeground] \ -troughcolor [resource scrollbarBackground] \ -borderwidth 1 -relief flat \ -highlightthickness 0 pack .f2.lb -side left -fill both -expand true pack .f2.sb -side right -fill y frame .f4 -relief sunken -borderwidth 2 label .f4.l -text "Private Sessions" \ -font [option get . infoFont Sdr] \ -relief raised -borderwidth 1 pack .f4.l -side top -fill x text .f4.lb -width 20 -height 3 -yscroll ".f4.sb set" \ -relief flat -wrap none \ -selectforeground [resource activeForeground] \ -selectbackground [resource activeBackground] \ -highlightthickness 0 init_session_list priv .f4.lb scrollbar .f4.sb -command ".f4.lb yview" \ -background [resource scrollbarForeground] \ -troughcolor [resource scrollbarBackground] \ -borderwidth 1 -relief flat \ -highlightthickness 0 pack .f4.lb -side left -fill both -expand true pack .f4.sb -side right -fill y } else { destroy .f3 } frame .f3 menubutton .f3.new -relief raised -menu .f3.new.m \ -padx 0 -pady 1 -borderwidth 1 -highlightthickness 0 -takefocus 1 menu .f3.new.m -tearoff 0 .f3.new.m add command -label [tt "Create advertised session"] \ -command {new new} .f3.new.m add command -label [tt "Quick Call"] -command {qcall} button .f3.cal -relief raised -command {calendar} \ -padx 0 -pady 1 -borderwidth 1 -highlightthickness 0 tixAddBalloon .f3.cal Button [tt "Display a calendar listing booked sessions"] button .f3.prefs -relief raised -command {preferences2} \ -padx 0 -pady 1 -borderwidth 1 -highlightthickness 0 tixAddBalloon .f3.prefs Button [tt "Set the way sdr does things"] #AUTH menubutton .f3.help -relief raised -menu .f3.help.m \ -padx 0 -pady 1 -borderwidth 1 -highlightthickness 0 -takefocus 1 menu .f3.help.m -tearoff 0 .f3.help configure -text [tt "Help"] #AUTH .f3.help.m add command -label [tt "sdr Help"] \ -command {help} #tixAddBalloon .f3.help.m Button "Turn these help messages on and off" .f3.help.m add command -label [tt "key setup"] -command {Help_asym asym_help} # button .f3.help -text [tt "Help"] -relief raised -command {help} \ # -padx 0 -pady 1 -borderwidth 1 -highlightthickness 0 # button .f3.help -text [tt "Help"] -relief raised -command {help} \ # -padx 0 -pady 1 -borderwidth 1 -highlightthickness 0 # tixAddBalloon .f3.help Button "Turn these help messages on and off" button .f3.quit -text [tt "Quit"] -relief raised -command quit \ -padx 0 -pady 1 -borderwidth 1 -highlightthickness 0 tixAddBalloon .f3.quit Button [tt "Quit from sdr. Conference tools already running will continue."] if {$lb=="short"} { .f3.new configure -text [tt "New"] .f3.cal configure -text [tt "Calendar"] .f3.prefs configure -text [tt "Prefs"] } else { .f3.new configure -text " [tt "Create Session"] " .f3.cal configure -text " [tt "Daily Listings"] " .f3.prefs configure -text " [tt "Preferences"] " .f3.help configure -text " [tt Help] " .f3.quit configure -text " [tt Quit] " } hlfocus .f3.new hlfocus .f3.cal hlfocus .f3.prefs hlfocus .f3.help hlfocus .f3.quit pack .f3.new -side left -fill both -pady 0 -expand true pack .f3.cal -side left -fill both -pady 0 -expand true pack .f3.prefs -side left -fill both -pady 0 -expand true pack .f3.help -side left -fill both -pady 0 -expand true pack .f3.quit -side left -fill both -pady 0 -expand true if {$first=="first"} { pack .f3 -side top -fill x pack .f1 -side bottom -fill x pack .f2 -side top -fill both -expand true bind_listbox norm bind_listbox priv } else { pack .f3 -side top -before .f2 -fill x } } proc bind_listbox {list} { global sessbox ix tcl_platform set lb $sessbox($list) #XXX bind $lb <1> {break} bind $lb <2> {break} bind $lb {break} bind $lb {break} bind $lb {break} bind $lb {break} bind $lb {break} bind $lb "focus $lb" bind $lb "focus ." bind $lb "scroll_to_session %K $list; break" tixAddBalloon $lb Listbox "Click button 1 on a listed session for more information on it or to participate in it. Click button 2 on a listed session to participate in it without displaying the session information Click button 3 on a listed session to hide the session if you're showing only preferred sessions" return 0 all this lot is obsolete... bind $lb <1> [format { tkListboxBeginSelect %%W [%%W index @%%x,%%y]; set tmp 0; catch { set tmp $ix(%s,[lindex [%s curselection] 0 ]); if {[ispopped $tmp]==1} { popdown $tmp } else { popup $tmp $ifstyle(view) advert } } } $list $lb] if {$tcl_platform(platform) == "windows"} { # tcl under windows only has buttons 1 & 3 bind $lb <3> [format { tkListboxBeginSelect %%W [%%W index @%%x,%%y] immediate_start %s [lindex [%s curselection] 0 ] } $list $lb] bind $lb {break} bind $lb <2> [format { tkListboxBeginSelect %%W [%%W index @%%x,%%y] hide_session %s [lindex [%s curselection] 0 ] } $list $lb] } else { bind $lb <2> [format { tkListboxBeginSelect %%W [%%W index @%%x,%%y] immediate_start %s [lindex [%s curselection] 0 ] } $list $lb] bind $lb {break} bind $lb <3> [format { tkListboxBeginSelect %%W [%%W index @%%x,%%y] hide_session %s [lindex [%s curselection] 0 ] } $list $lb] } bind $lb k {tkListboxUpDown %W -1} bind $lb j {tkListboxUpDown %W 1} } proc quit {} { #AUTH global log env global logfile give_status_msg "Writing cache files..." update idletasks write_cache log "Sdr exiting (Quit button pressed) at [getreadabletime]" savelog if [info exists env(X509STATE)] { set pgpdir "[glob -nocomplain ~]/.pgp" if [info exists env(PGPPATH)] { set env(PGPPATH) $env(PGPPATH) } else { if { [file isdirectory $pgpdir ] == 0} { if { [ enter_pgp_path] == 0 } { return 0 } } else { set env(PGPPATH) $pgpdir } } if { [file exists $env(PGPPATH)/secring.enc] } { if {[ info exists env(SMARTLOC)]} { set env(USERPIN) $env(SMARTPIN) set tclcmd [ list exec secude pkcs7enc ENVELOPED-DATA -p $env(SMARTLOC) -i $env(PGPPATH)/secring.pgp -o $env(PGPPATH)/secring.enc ] set result [ catch $tclcmd output] file delete $env(PGPPATH)/secring.pgp } } else { if { [pgp_smart "SMARTCARD" "Would you like to use smart card to encrypt your PGP secring file" "YES" ] != 0 } { if { [pgp_smart "SMARTCARD" " Place your smartcard" "OK"] != 0 } { if { [enter_smart_pse_details] != 0 } { set result [Misc_CheckSmart $env(SMARTPIN) $env(SMARTLOC)] set i 0 while {$i == 0 } { if { $result == 1} { set env(USERPIN) $env(SMARTPIN) set pgpdir "[glob -nocomplain ~]/.pgp" if [info exists env(PGPPATH)] { set env(PGPPATH) $env(PGPPATH) } else { if { [file isdirectory $pgpdir ] == 0} { if { [ enter_pgp_path] == 0 } { return 0 } } else { set env(PGPPATH) $pgpdir } } set tclcmd [ list exec secude pkcs7enc ENVELOPED-DATA -p $env(SMARTLOC) -i $env(PGPPATH)/secring.pgp -o $env(PGPPATH)/secring.enc ] set result [ catch $tclcmd output] file delete $env(PGPPATH)/secring.pgp set i 1 } else { catch {unset env(SMARTLOC)} catch {unset env(SMARTPIN)} if {[enter_smart_pse_details ] == 0} { set i 1 } else { set result [Misc_CheckSmart $env(SMARTPIN) $env(SMARTLOC) ] } } } } } } } } if { [file exists $logfile] } { # file delete $logfile } ui_quit destroy . } proc give_status_msg {text} { global titlestr .f1.l configure -text $text -font [option get . italfont Sdr] after 2000 .f1.l configure -text \"$titlestr\" -font [option get . font Sdr] } set fullnumitems 0 set medianum 0 #set tfrom 0 #set tto 0 proc reset_media {} { #ensure that Tcl's error recovery hasn't left any unwanted state around global vars port proto fmt medianum advertid global session multicast recvttl recvsap_addr recvsap_port desc advertid creator tfrom tto global source heardfrom timeheard global starttime endtime uri email phone catch {unset media} catch {unset vars} catch {unset port} catch {unset proto} catch {unset fmt} set medianum 0 catch {unset advertid} catch {unset session} set multicast 0 catch {unset recvttl} catch {unset recvsap_addr} catch {unset recvsap_port} catch {unset desc} catch {unset creator} # set tto 0 # set tfrom 0 set uri 0 catch {unset source} catch {unset heardfrom} catch {unset timeheard} catch {unset starttime} catch {unset endtime} catch {unset sessvars} catch {unset trust} catch { foreach i [array names email] { unset email($i) } } catch { foreach i [array names phone] { unset phone($i) } } } proc media_changed_warning {aid medianum} { global ldata ifstyle tcl_platform if {$tcl_platform(platform) == "unix"} { set pid $ldata($aid,$medianum,pid) if {$pid!=0} { switch $tcl_platform(os) { #wouldn't it be nice if this was portable... SunOS { set ps "/usr/ucb/ps " } Linux { set ps "ps " } default {set ps "ps -p "} } } else { return 1 } set psout "" catch {set psout [eval exec $ps $pid]} if {[string first $pid $psout] == -1} { set ldata($aid,$medianum,pid) 0 return 1 } catch {destroy .mediawarn} toplevel .mediawarn$aid wm title .mediawarn$aid "Sdr: Warning" frame .mediawarn$aid.f -borderwidth 2 -relief groove set win .mediawarn$aid.f pack $win -side top -fill both label $win.l -text [tt "Warning: Session has been modified"] pack $win.l -side top -fill x -expand true message $win.m -aspect 500 -text \ [concat [tt "The session called:\n"] \ $ldata($aid,session) \ [tt "has been modified.\n\n"]\ [tt "You are advised to restart the tools you have running for this session."]] pack $win.m -side top -fill x -expand true frame $win.f -borderwidth 0 pack $win.f -side top -fill x -expand true button $win.f.show -text "Show details" \ -command "catch {destroy .mediawarn$aid};popup $aid $ifstyle(view) advert" pack $win.f.show -side left -fill x -expand true button $win.f.dismiss -text "Dismiss" \ -command "catch {destroy .mediawarn$aid}" \ -highlightthickness 0 pack $win.f.dismiss -side left -fill x -expand true return 0 } else { return 0 } } proc set_media {} { global media vars port proto fmt medianum ldata advertid global mediaaddr mediattl medialayers rtp_payload global mediakey set origaddr 0 set aid $advertid catch { set origaddr $ldata($aid,$medianum,addr) set origport $ldata($aid,$medianum,port) } if {($origaddr!=0)&&($ldata($aid,started)==1)} { if {($origaddr!=$mediaaddr)||($origport!=$port)} { set $ldata($aid,started) \ [media_changed_warning $aid $medianum] } } set ldata($aid,$medianum,media) $media set ldata($aid,$medianum,port) $port set ldata($aid,$medianum,proto) $proto set ldata($aid,$medianum,fmt) $fmt set ldata($aid,$medianum,vars) $vars set ldata($aid,$medianum,addr) $mediaaddr set ldata($aid,$medianum,layers) $medialayers set ldata($aid,$medianum,ttl) $mediattl set ldata($aid,$medianum,pid) 0 set ldata($aid,$medianum,mediakey) $mediakey incr medianum set ldata($aid,medianum) $medianum debug "medianum=$medianum" } proc add_to_list {} { global session multicast recvttl recvsap_addr recvsap_port desc global advertid creator tfrom tto global ldata fullnumitems fullix medianum source items global heardfrom timeheard global starttime endtime showwhich phone email uri rctr repeat global createtime modtime createaddr sessvars trust recvkey global debug1 #AUTH global asym_cur_keyid global sess_auth_status global sess_auth_type global sess_auth_message global enc_asym_cur_keyid global sess_enc_status global sess_enc_type global sess_enc_message global asympse #end if {$debug1 == 1} { putlogfile "add_to_list $advertid" } set aid $advertid set code 0 debug "add_to_list $session key:$recvkey" catch {set code $ldata($aid,session);set code 1} if {$code==0} { set ldata($aid,trust) $trust set ldata($aid,started) 0 } elseif {$ldata($aid,trust)=="sip"} { #we first heard the announcement via SIP and now hear it via SAP #update the trust accordingly set ldata($aid,trust) $trust #probably the session will also need to change listboxes... if {$ldata($aid,list)!=""} { incr items($ldata($aid,list)) -1 set ldata($aid,list) "" resort_sessions set code 0 } } #AUTH set asympse {} set ldata($aid,authtype) $sess_auth_type set ldata($aid,authstatus) $sess_auth_status set ldata($aid,authmessage) $sess_auth_message set ldata($aid,asym_keyid) $asym_cur_keyid set ldata($aid,enctype) $sess_enc_type set ldata($aid,encstatus) $sess_enc_status set ldata($aid,enc_asym_keyid) $enc_asym_cur_keyid set ldata($aid,encmessage) $sess_enc_message #end set ldata($aid,key) $recvkey set ldata($aid,createtime) $createtime set ldata($aid,modtime) $modtime set ldata($aid,createaddr) $createaddr set ldata($aid,source) $source set ldata($aid,heardfrom) $heardfrom set ldata($aid,session) $session set ldata($aid,multicast) $multicast set ldata($aid,ttl) $recvttl set ldata($aid,sap_addr) $recvsap_addr set ldata($aid,sap_port) $recvsap_port # regsub -all {\\n} $desc "\n" desc set ldata($aid,desc) $desc set ldata($aid,creator) $creator set ldata($aid,theard) $timeheard set ldata($aid,starttime) 0 set ldata($aid,endtime) 0 set ldata($aid,tto) "" set ldata($aid,tfrom) "" set ldata($aid,method) advert set ldata($aid,vars) $sessvars set ldata($aid,type) unknown set ldata($aid,tool) unknown foreach i [split $sessvars "\n"] { set attr [lindex [split $i ":"] 0] switch $attr { tool { set ldata($aid,tool) [lindex [split $i ":"] 1] } type { set ldata($aid,type) [lindex [split $i ":"] 1] } } } foreach i [array names starttime] { set ldata($aid,tto,$i) $tto($i) set ldata($aid,tfrom,$i) $tfrom($i) set ldata($aid,starttime,$i) $starttime($i) if {($starttime($i) < $ldata($aid,starttime)) || \ ($ldata($aid,starttime)==0)} { set ldata($aid,starttime) $starttime($i) set ldata($aid,tfrom) $tfrom($i) } set ldata($aid,endtime,$i) $endtime($i) if {$endtime($i) > $ldata($aid,endtime)} { set ldata($aid,endtime) $endtime($i) set ldata($aid,tto) $tto($i) } set ro 0 for {set r 0} {$r < $rctr($i)} {incr r} { #don't accept repeat intervals of zero or less set interval [parse_rpt_time [lindex $repeat($i,$r) 0]] if {$interval>0} { set duration [parse_rpt_time [lindex $repeat($i,$r) 1]] # If the duration is longer than or equal to the interval, then it # effectively means "the whole time". if {$duration >= $interval} { # XXX # Need to increment the start of the session by the # first offset if it's not 0. # set a [parse_rpt_time [lindex $repeat($i,$r) 0]] # if {$a != 0} { # add $a to tfrom # add $a to starttime # } set ro 0 break } set r2 -1 for {set j 0} {$j < $ro} {incr j} { if {($ldata($aid,time$i,interval$j) == $interval) && \ ($ldata($aid,time$i,duration$j) == $duration)} { set r2 $j break } } if {$r2 == -1} { set ldata($aid,time$i,interval$ro) $interval set ldata($aid,time$i,duration$ro) $duration set ldata($aid,time$i,offset$ro) {} set r2 $ro incr ro } for {set j 2} {$j < [llength $repeat($i,$r)]} {incr j} { lappend ldata($aid,time$i,offset$r2) \ [parse_rpt_time [lindex $repeat($i,$r) $j]] } } } set ldata($aid,time$i,no_of_rpts) $ro } set ldata($aid,no_of_times) [array size starttime] set ldata($aid,lastheard) [gettimeofday] set ldata($aid,emaillist) "" set ldata($aid,uri) $uri catch { foreach i [array names email] { lappend ldata($advertid,emaillist) $email($i) } } set ldata($aid,phonelist) "" catch { foreach i [array names phone] { lappend ldata($advertid,phonelist) $phone($i) } } if {$medianum==0} { set ldata($aid,medianum) 0 } set medianum 0 display_session $aid $code # set tfrom 0 # set tto 0 } proc clear_session_state {aid} { global ldata #this way of doing things isn't very efficient but is effective foreach tag [array names ldata] { set lst [split $tag ","] if {[string compare [lindex $lst 0] $aid]==0} { unset ldata($tag) } } } proc display_session {aid code} { global ldata session debug "display_session $aid $code" if {$code == 0} { #we haven't heard an announcement of this session before if {($ldata($aid,endtime)!=0)&&([gettimeofday] > $ldata($aid,endtime))} { #the session has now timed out (can only happen due to clock skew) debug "\"$session\" out of date $ldata($aid,endtime)" set medianum 0 # set tfrom 0 # set tto 0 #do a little cleaning up clear_session_state $aid return } #is it a private session? #actually display it #AUTH if {$ldata($aid,key)!=""} { add_to_display_list $aid priv } else { if { ($ldata($aid,enctype) == "x509")||($ldata($aid,enctype) == "pgp") } { add_to_display_list $aid priv } else { add_to_display_list $aid norm } } set ldata($aid,is_popped) -1 sdr_new_session_hook $aid } else { catch { #we've heard it before update_displayed_session $aid } } } proc add_to_display_list {aid list} { global items ix ldata sessbox showwhich fullnumitems fullix debug "new session $ldata($aid,session) in list $list" # debug "with endtime [gettime $ldata($aid,endtime)]" #check if it's already displayed foreach index [array names ix] { if {[string compare "[string range $index 0 3],$ix($index)" "$list,$aid"]==0} { debug "session already displayed - why are we here?" return 0 } } set ldata($aid,list) $list #check it's not in the list of sessions not to show set vstate 1 catch {set vstate $ldata($aid,vstate)} if {$vstate == 1} { set ldata($aid,vstate) 1 } else { debug "session is in list of sessions to hide" return 0 } #check it satisfies the display criteria if {[listing_criteria $aid $showwhich]!=1} { catch {unset $ldata($aid,lastix)} return 0 } set lsession [string tolower $ldata($aid,session)] set lastix 0 set i 0 debug a while {($i < $fullnumitems) && \ ([compare $aid $fullix($i)]<0)} { if {($lastix < $items($list)) && \ ([string compare $ix($list,$lastix) $fullix($i)]==0)} { incr lastix } incr i } debug b for {set j $fullnumitems} {$j > $i} {incr j -1} { set fullix($j) $fullix([expr $j - 1]) } incr fullnumitems set fullix($i) $aid debug c for {set j $items($list)} {$j > $lastix} {incr j -1} { set ix($list,$j) $ix($list,[expr $j - 1]) } debug d #Display it set ix($list,$lastix) $aid list_session $aid $lastix $list if {$items($list) == 0} { show_session_list $list } incr items($list) } #AUTH proc list_session {aid lastix list} { global sessbox ldata ifstyle #puts "$ldata($aid,session)" set newname $ldata($aid,session) if {$ldata($aid,trust)!="sip"} { set autht $ldata($aid,authtype) set enct $ldata($aid,enctype) if { $ldata($aid,authtype) != "none" } { set authtest $ldata($aid,authtype) set newname [concat $newname "(" $authtest ")"] } if { $ldata($aid,enctype)!="none" } { set enctest $ldata($aid,enctype) set newname [concat $newname "(" $enctest ")"] } } else { set autht "none" set enct "none" } if {$ifstyle(list)=="logo"} { set type $ldata($aid,type) if {[winfo exists $sessbox($list).win$aid]==0} { putlogfile "creating new window $sessbox($list).win$aid" label $sessbox($list).win$aid \ -bitmap [get_type_icon $ldata($aid,type) $autht $enct] \ -borderwidth 2 -relief groove bind $sessbox($list).win$aid \ "highlight_tag $aid enter" bind $sessbox($list).win$aid \ "highlight_tag $aid leave" bind $sessbox($list).win$aid <1> "toggle_popup $aid" bind $sessbox($list).win$aid <2> "start_all $aid" bind $sessbox($list).win$aid <3> "hide_session $aid" } #puts "$sessbox($list) window create ..." $sessbox($list) window create [expr $lastix+1].0 -window \ $sessbox($list).win$aid $sessbox($list) insert [expr $lastix+1].1 "$newname \n" } else { #wish there was a better was to add a tag to the right margin $sessbox($list) insert [expr $lastix+1].0 "$newname \n" } # PCs will crash here if the scrollbar is being used at the same time..... $sessbox($list) tag add t$aid [expr $lastix+1].0 [expr $lastix+1].end $sessbox($list) tag bind t$aid <1> "toggle_popup $aid" $sessbox($list) tag bind t$aid <2> "start_all $aid" $sessbox($list) tag bind t$aid <3> "hide_session $aid" $sessbox($list) tag bind t$aid \ "highlight_tag $aid enter" $sessbox($list) tag bind t$aid \ "highlight_tag $aid leave" if {[ispopped $aid]==1} { $sessbox($list) tag configure t$aid \ -foreground [option get . background Sdr] \ -background [option get . foreground Sdr] catch {$sessbox($ldata($aid,list)).win$aid configure \ -foreground [option get . background Sdr] \ -background [option get . foreground Sdr] } } elseif {[listing_criteria $aid future]==1} { $sessbox($list) tag configure t$aid \ -foreground [option get . disabledForeground Sdr] \ -background [option get . background Sdr] catch {$sessbox($list).win$aid configure \ -foreground [option get . disabledForeground Sdr] \ -background [option get . background Sdr] } } else { $sessbox($list) tag configure t$aid \ -foreground [option get . foreground Sdr] \ -background [option get . background Sdr] } } proc relist_session {aid lastix list} { global sessbox ldata showwhich putlogfile "relist_session" if {[listing_criteria $aid $showwhich]!=1} { #this session just became unshown - better redisplay everything. reshow_sessions $showwhich putlogfile "reshow_sessions" return 0 } #did the session type or name change? set txt [$sessbox($list) get [expr $lastix+1].0 [expr $lastix+1].end+1c] set txt [string trim $txt "\n"] set txt [string trim $txt] putlogfile "new:>>$ldata($aid,session)<<, old:>>$txt<<" if {[string compare $ldata($aid,session) $txt]!=0} { $sessbox($list) delete [expr $lastix+1].0 [expr $lastix+1].end+1c list_session $aid $lastix $list } if {[ispopped $aid]==1} { highlight_tag $aid popup } } proc highlight_tag {aid mode} { global sessbox ldata set win 0 catch {set win $sessbox($ldata($aid,list))} #don't worry about it if the session already timed out if {$win==0} {return 0} set icon $sessbox($ldata($aid,list)).win$aid switch $mode { enter { if {[ispopped $aid]==1} { $win tag configure t$aid \ -foreground [option get . activeBackground Sdr] catch {$icon configure \ -foreground [option get . activeBackground Sdr]} } else { $win tag configure t$aid -background \ [option get . activeBackground Sdr] catch {$icon configure -background \ [option get . activeBackground Sdr]} } } leave { if {[ispopped $aid]==1} { $win tag configure t$aid \ -foreground [option get . background Sdr] catch {$icon configure \ -foreground [option get . background Sdr]} } else { $win tag configure t$aid \ -background [option get . background Sdr] catch {$icon configure \ -background [option get . background Sdr]} } } popup { $win tag configure t$aid \ -foreground [option get . background Sdr] \ -background [option get . foreground Sdr] catch {$icon configure \ -foreground [option get . background Sdr] \ -background [option get . foreground Sdr]} } popdown { if {[listing_criteria $aid future]==1} { $win tag configure t$aid \ -foreground [option get . disabledForeground Sdr] \ -background [option get . background Sdr] catch {$icon configure \ -foreground [option get . disabledForeground Sdr] \ -background [option get . background Sdr]} } else { $win tag configure t$aid \ -foreground [option get . foreground Sdr] \ -background [option get . background Sdr] catch {$icon configure \ -foreground [option get . foreground Sdr] \ -background [option get . background Sdr]} } } } } proc toggle_popup {aid} { global ifstyle if {[ispopped $aid]==1} { popdown $aid update } else { popup $aid $ifstyle(view) advert update } } proc show_session_list {list} { debug "show_session_list $list" if {$list=="priv"} { catch {pack .f4 -side top -fill both -expand true -after .f2} } debug "done" } set sesslists "" proc init_session_list {list box} { #initialise the data structures for a session listing box global items sessbox sesslists ifstyle if {$ifstyle(list)=="normal"} { $box configure -spacing1 4 } set sesslists "$sesslists $list" set sessbox($list) $box set items($list) 0 set ix($list) "" } proc update_displayed_session {aid} { global ldata sessbox showwhich if {[listing_criteria $aid $showwhich]!=1} { return 0 } set list $ldata($aid,list) if {[set visix [find_listbox_index $aid $list]]!=-1} { set loc [lindex [$sessbox($list) yview] 0] relist_session $aid $visix $list } set win $ldata($aid,is_popped) if {[winfo exists $win]} { #the window is visible popup_update $aid name $ldata($aid,session) popup_update $aid desc $ldata($aid,desc) popup_update $aid heard "Heard from $ldata($aid,heardfrom) at $ldata($aid,theard)" if {$ldata($aid,endtime)!=0} { popup_update $aid from "Session takes place from $ldata($aid,tfrom)" popup_update $aid to " to $ldata($aid,tto)" } for {set i 0} {$i < $ldata($aid,medianum)} {incr i} { set media $ldata($aid,$i,media) popup_update_media $aid $i \ $ldata($aid,$i,fmt) \ $ldata($aid,$i,proto) \ $ldata($aid,$i,port) \ $ldata($aid,$i,ttl) \ $ldata($aid,$i,addr) \ $ldata($aid,$i,layers) \ $ldata($aid,$i,mediakey) \ $ldata($aid,$i,vars) } } } proc parse_rpt_time {timestr} { set mult(s) 1 set mult(m) 60 set mult(h) 3600 set mult(d) 86400 set timestr [string trim $timestr] if {[regexp {^([-0-9]+)([dhms])$} $timestr junk num m]} { return [expr $num * $mult($m)] } else { return $timestr } } proc make_rpt_time {secs} { if {$secs == 0} { return $secs } elseif {[expr $secs % 86400]==0} { return "[expr $secs/86400]d" } elseif {[expr $secs % 3600]==0} { return "[expr $secs/3600]h" } elseif {[expr $secs % 60]==0} { return "[expr $secs/60]m" } else { return $secs } } proc reshow_sessions {spec} { global ldata fullnumitems fullix items ix sessbox sesslists ifstyle foreach box [array names sessbox] { if {$ifstyle(list)=="normal"} { $sessbox($box) configure -spacing1 4 } else { $sessbox($box) configure -spacing1 0 } $sessbox($box) delete 1.0 end } foreach list $sesslists { set lastix($list) 0 } foreach index [array names ix] { unset ix($index) } for {set i 0} {$i < $fullnumitems} {incr i} { set aid $fullix($i) set list $ldata($aid,list) if {$list==""} {continue} # if {$lastix < $items($list)} { # set showing [expr [string compare $ix($list,$lastix) $aid] == 0] # } else { # set showing 0 # } set show [listing_criteria $aid $spec] if {$show} { set ix($list,$lastix($list)) $aid list_session $aid $lastix($list) $list incr lastix($list) } } } proc resort_sessions {} { global ldata fullix fullnumitems ix sesslists showwhich #this is an insertion sort. #really should be something faster than this :-( set lastix 0 foreach item [array names fullix] { set aid $fullix($item) set newi 0 while {($newi<$lastix)&&([compare $aid $newfullix($newi)]<0)} { incr newi } for {set i [expr $lastix-1]} {$i>=$newi} {incr i -1} { set newfullix([expr $i+1]) $newfullix($i) } set newfullix($newi) $aid incr lastix } foreach item [array names newfullix] { set fullix($item) $newfullix($item) unset newfullix($item) } reshow_sessions $showwhich } set typevalue(test) -1 set typevalue(meeting) 1 set typevalue(broadcast) 2 #AUTH set typevalue(stest) -1 set typevalue(smeeting) 1 set typevalue(sbroadcast) 2 #set typevalue(secure) 3 proc compare {aid1 aid2} { global ifstyle typevalue ldata set title1 [string toupper $ldata($aid1,session)] set title2 [string toupper $ldata($aid2,session)] switch $ifstyle(order) { alphabetic { return [string compare $title2 $title1] } type { set type1 $ldata($aid1,type) set type2 $ldata($aid2,type) if {$type1==$type2} { return [string compare $title2 $title1] } else { set tv1 0 set tv2 0 catch {set tv1 $typevalue($type1)} catch {set tv2 $typevalue($type2)} return [expr $tv1-$tv2] } } } } proc listing_criteria {aid spec} { global ldata showwhichfilter foreach filter [array names showwhichfilter] { if {($showwhichfilter($filter)==1) && \ ($ldata($aid,type)==$filter)} { return 0 } } case $spec { all { return 1 } pref { return $ldata($aid,vstate) } current { if {$ldata($aid,starttime)>[gettimeofday]} { return 0 } else { return 1 } } future { if {$ldata($aid,starttime)>[gettimeofday]} { return 1 } else { return 0 } } } } proc find_listbox_index {aid list} { global ix items for {set i 0} {$i < $items($list)} {incr i} { if {[string compare $ix($list,$i) $aid]==0} { return $i } } return -1 } proc find_full_index {aid} { global fullix for {set i 0} {$i < [array size fullix]} {incr i} { if {[string compare $fullix($i) $aid]==0} { return $i } } return -1 } set timeout 3600 proc timeout_expired_sessions {} { global ix ldata items timeout fullnumitems fullix sessbox #run this again in 5 mins #set it before anything else to make it more robust to failures in #any of the following code after 120000 timeout_expired_sessions set time [gettimeofday] #search through the full index for timed out sessions set no_of_sess 0 catch {set no_of_sess [array size fullix]} for {set i 0} {$i < $no_of_sess} {incr i} { set aid $fullix($i) set endtime $ldata($aid,endtime) set list $ldata($aid,list) #has it timed out? if {(($endtime!=0)&&($time>$endtime)) | \ ([expr $time-$ldata($aid,lastheard)]>$timeout)} { sdr_delete_session_hook $aid #if the session was displayed in the listbox, delete it set visix [find_listbox_index $aid $list] if {$visix != -1} { $sessbox($list) delete [expr $visix+1].0 [expr $visix+1].end+1c for {set j $visix} {$j < [expr $items($list)-1]} {incr j} { set ix($list,$j) $ix($list,[expr $j + 1]) } unset ix($list,[expr $items($list)-1]) incr items($list) -1 } #clear out the old state clear_session_state $aid #remove it from the full index for {set j $i} \ {$j < [expr [array size fullix]-1]} {incr j} { set fullix($j) $fullix([expr $j + 1]) } unset fullix([expr [array size fullix]-1]) incr fullnumitems -1 incr no_of_sess -1 } } } #and ensure it runs the first time after 120000 timeout_expired_sessions proc popdown {aid} { set wname .desc$aid highlight_tag $aid popdown catch "destroy $wname" update } proc ispopped {aid} { global ldata return [winfo exists .desc$aid] } proc null {} { } proc highlight_url {win {inbrowser 0}} { set tagnum 0 regexp {[0-9]+} [$win index end] lastline for {set i 1} {$i < $lastline} {incr i} { set line [$win get $i.0 "$i.0 lineend"] set start [string first "http:/" $line] set begin 0 while { $start > -1 } { set begin [expr $begin+$start] set url [$win get $i.$begin "$i.0 lineend"] set end [string length $url] set tmp [string first " " $url] if { ($tmp < $end) && ($tmp > -1) } { set end $tmp } set tmp [string first ". " $url] if { ($tmp < $end) && ($tmp > -1) } { set end $tmp } set tmp [string first ", " $url] if { ($tmp < $end) && ($tmp > -1) } { set end $tmp } set tmp [string first ">" $url] if { ($tmp < $end) && ($tmp > -1) } { set end $tmp } set tmp [string first "\"" $url] if { ($tmp < $end) && ($tmp > -1) } { set end $tmp } set tmp [string first ")" $url] if { ($tmp < $end) && ($tmp > -1) } { set end $tmp } incr tagnum set url$tagnum [string range $url 0 [expr $end-1]] $win tag add url$tagnum $i.$begin $i.[expr $end+$begin] set begin [expr $end+$begin+1] set line [string range $line $begin end] set start [string first "http:/" $line] } } for {set i 1} {$i <= $tagnum} {incr i} { $win tag configure url$i \ -foreground [option get . hotForeground Sdr] $win tag configure url$i -relief raised if {$inbrowser} { $win tag bind url$i <1> \ "set urilist \"\[lrange \$urilist 0 \$uriix] [set url$i]\"; \ set uriix \[expr \[llength \$urilist] -1];\ webdisp [set url$i]" $win tag bind url$i \ "$win tag configure url$i \ -foreground [option get . activehotForeground Sdr];\ overhref [set url$i]" $win tag bind url$i \ "$win tag configure url$i \ -foreground [option get . hotForeground Sdr];\ overhref" } else { $win tag bind url$i <1> \ "get_uri [set url$i]" $win tag bind url$i \ "$win tag configure url$i \ -foreground [option get . activehotForeground Sdr]" $win tag bind url$i \ "$win tag configure url$i \ -foreground [option get . hotForeground Sdr]" } } } proc bounce_phone {win} { if {[winfo exists $win]} { switch [lindex [$win configure -bitmap] 4] { phone1 { $win configure -bitmap phone3 after 70 "bounce_phone $win" } phone2 { $win configure -bitmap phone4 after 70 "bounce_phone $win" } phone3 { $win configure -bitmap phone2 after 70 "bounce_phone $win" } phone4 { $win configure -bitmap phone1 after 400 "bounce_phone $win" } } } } proc popup {aid ifstyle msgsrc} { global ldata lang # if {$i==""} {return} # set aid $ix($i) if {[string compare $aid ""]==0} return set wname .desc$aid catch {destroy $wname} toplevel $wname set ldata($aid,is_popped) .desc$aid catch {highlight_tag $aid popup} #commented out because it destroys SIP popups incorrectly # uplevel trace variable ldata($aid,session) u "\"destroy .desc$aid\"" frame $wname.f -relief groove -borderwidth 2 set win $wname.f pack $win -side top -fill both -expand true set infofont "[option get . infoFont Sdr]" #AUTH #Determine the background colour of the title bar by checking #authentication status. if {($msgsrc=="advert") && ($ldata($aid,trust)!="sip")} { set auth $ldata($aid,authstatus) set enc $ldata($aid,encstatus) set autht $ldata($aid,authtype) set enct $ldata($aid,enctype) set authm $ldata($aid,authmessage) set encm $ldata($aid,encmessage) switch $auth { noauth { set bgcolour "lightblue" switch $enc { failed { set fgcolour "blue" } Encrypted { set fgcolour "navy" } success { set fgcolour "red" } SUCCESS { set fgcolour "orange" } noenc { set fgcolour "brown" } NOENC { set fgcolour "black" } default { set fgcolour "blue" } } } failed { set bgcolour "pink" switch $enc { failed { set fgcolour "cadleblue" } success { set fgcolour "red" } Encrypted { set fgcolour "navy" } SUCCESS { set fgcolour "orange" } noenc { set fgcolour "brown" } NOENC { set fgcolour "black" } default { set fgcolour "blue" } } } trustworthy { set bgcolour "green" switch $enc { failed { set fgcolour "cadleblue" } Encrypted { set fgcolour "navy" } success { set fgcolour "red" } SUCCESS { set fgcolour "orange" } noenc { set fgcolour "brown" } NOENC { set fgcolour "black" } default { set fgcolour "blue" } } } authenticated { set bgcolour "skyblue" switch $enc { failed { set fgcolour "cadleblue" } Encrypted { set fgcolour "navy" } success { set fgcolour "red" } SUCCESS { set fgcolour "orange" } noenc { set fgcolour "brown" } NOENC { set fgcolour "black" } default { set fgcolour "blue" } } } integrity { set bgcolour "yellowgreen" switch $enc { failed { set fgcolour "cadleblue" } Encrypted { set fgcolour "navy" } success { set fgcolour "red" } SUCCESS { set fgcolour "orange" } noenc { set fgcolour "brown" } NOENC { set fgcolour "black" } default { set fgcolour "blue" } } } TRUSTWORTHY { set bgcolour "yellow" switch $enc { failed { set fgcolour "cadleblue" } Encrypted { set fgcolour "navy" } success { set fgcolour "red" } SUCCESS { set fgcolour "orange" } noenc { set fgcolour "brown" } NOENC { set fgcolour "black" } default { set fgcolour "blue" } } } FAILED { set bgcolour "lightsalmon" switch $enc { failed { set fgcolour "cadleblue" } Encrypted { set fgcolour "navy" } success { set fgcolour "red" } SUCCESS { set fgcolour "orange" } noenc { set fgcolour "brown" } NOENC { set fgcolour "black" } default { set fgcolour "blue" } } } INTEGRITY { set bgcolour "limegreen" switch $enc { failed { set fgcolour "cadleblue" } Encrypted { set fgcolour "navy" } success { set fgcolour "red" } SUCCESS { set fgcolour "orange" } noenc { set fgcolour "brown" } NOENC { set fgcolour "black" } default { set fgcolour "blue" } } } NOAUTH { set bgcolour "cyan" switch $enc { failed { set fgcolour "cadleblue" } Encrypted { set fgcolour "navy" } success { set fgcolour "red" } SUCCESS { set fgcolour "orange" } noenc { set fgcolour "brown" } NOENC { set fgcolour "black" } default { set fgcolour "blue" } } } default { set bgcolour "lightpink" switch $enc { failed { set fgcolour "cadleblue" } Encrypted { set fgcolour "navy" } success { set fgcolour "red" } SUCCESS { set fgcolour "orange" } noenc { set fgcolour "brown" } NOENC { set fgcolour "cadleblue" } default { set fgcolour "black" } } } } } else { set auth "sip" set enc "sip" set autht "none" set enct "none" set authm "none" set encm "none" switch $auth { sip { set bgcolour "yellow" switch $enc { sip { set fgcolour "black" } default { set fgcolour "red" } } } } } #end if {$msgsrc=="advert"} { wm title $wname "Sdr: Session Information" } else { wm title $wname "Sdr: Incoming call from $msgsrc" frame $win.inv -borderwidth 2 -relief groove pack $win.inv -side top -fill x -expand true label $win.inv.l -text "Incoming Call" -font [option get . largeFont Sdr] pack $win.inv.l -side top frame $win.inv.f -borderwidth 0 pack $win.inv.f -side top -fill x -expand true label $win.inv.f.phone -bitmap phone1 after 200 "bounce_phone $win.inv.f.phone" pack $win.inv.f.phone -side left message $win.inv.f.m -aspect 800 -text "You have an incoming call from $msgsrc inviting you to join the following session" pack $win.inv.f.m -side left -fill x -expand true posn_win_midscreen $wname } #AUTH - added "-background $bgcolour for AUTHENTICATION and \" below # Fg for Encryption frame $win.sn -borderwidth 0 #AUTH button $win.sn.icon -bitmap [get_type_icon $ldata($aid,type) $autht $enct]\ -relief flat -borderwidth 0 \ -padx 0 -pady 0 -highlightthickness 0 \ -command "explain_icon $win.sn.icon \"session is a $ldata($aid,type)\"" pack $win.sn.icon -side left #label $win.sn.l -text $ldata($aid,session) -anchor n #log "displaying details of session called:\n $ldata($aid,session) \n at [getreadabletime]" #pack $win.sn.l -side left -fill x -expand true #AUTH - added "-bg $bgcolour \" below # label $win.sn.l -text "Encryption: $enc $enct $ldata($aid,session) \ # Authentication: $auth $autht" -anchor n -bg $bgcolour -fg $fgcolour label $win.sn.l -text "Session: $ldata($aid,session) Encryption: $enc $enct \ Authentication: $auth $autht" -anchor n -bg $bgcolour -fg $fgcolour pack $win.sn.l -side left -fill x -expand true #end AUTH frame $win.f0 -relief ridge -borderwidth 2 text $win.f0.desc -width 40 -height 5 -wrap word -relief flat \ -yscroll "$win.f0.sb set" -highlightthickness 0 bind $win.f0.desc <1> {null} bind $win.f0.desc {null} scrollbar $win.f0.sb -command "$win.f0.desc yview" \ -background [resource scrollbarForeground] \ -troughcolor [resource scrollbarBackground] \ -borderwidth 1 -relief flat \ -highlightthickness 0 #TBD # -activeforeground [option get . scrollbarActiveForeground Sdr] \ # -foreground [option get . scrollbarForeground Sdr] # $win.f0.desc insert 0.0 [text_wrap $ldata($aid,desc) 40] $win.f0.desc insert 0.0 $ldata($aid,desc) $win.f0.desc configure -state disabled pack $win.sn -side top -fill x pack $win.f0.sb -side right -fill y pack $win.f0.desc -side left -fill both -expand true pack $win.f0 -side top -expand true -fill both highlight_url $win.f0.desc set mf [option get . mediumFont Sdr] pack [frame $win.hidden1 -width 1 -height 1] -side top -padx 0 -pady 0 if {$ldata($aid,tfrom)!=0} { # if {($ldata($aid,no_of_times)>1)||($ldata($aid,time0,no_of_rpts)>0)} { case $lang in { {C En} {show_times_english $win $aid} default {show_times_english $win $aid} } # } else { # pack [frame $win.linfo -borderwidth 2 -relief groove] -side top -fill x # label $win.linfo.from -font $mf # label $win.linfo.to -font $mf # $win.linfo.from configure -text "[tt "Session takes place from"] [cropdate $ldata($aid,tfrom)] [croptime $ldata($aid,tfrom)]" # $win.linfo.to configure -text "[tt to] $ldata($aid,tto)" # pack $win.linfo.from -side top # pack $win.linfo.to -side top # } } pack [frame $win.hidden2 -width 1 -height 1] -side top -padx 0 -pady 0 global $win.visible set $win.visible 0 frame $win.buttons -borderwidth 2 -relief groove pack $win.buttons -side top -fill x -expand true if {$authm != "none" || $encm != "none" } { if {$authm != "none" } { # frame $win.authmsg -borderwidth 0 #label $win.authmsg.l -text "$authm " -anchor n -bg $bgcolour -fg $fgcolour #pack $win.authmsg.l -side left -fill x -expand true iconbutton $win.buttons.authmsg -text "Authentication Info" -relief raised \ -borderwidth 1 -command "authinfo $win $bgcolour $fgcolour \"$authm\" "\ -font [option get . mediumFont Sdr] -pad 1 tixAddBalloon $win.buttons.authmsg Frame [tt "Display the Authentication Security Information."] incr $win.visible pack $win.buttons.authmsg -side left -fill x -expand true } if {$encm != "none" } { iconbutton $win.buttons.encmsg -text "Encryption Info" -relief raised \ -borderwidth 1 -command "encinfo $win $bgcolour $fgcolour \"$encm\" "\ -font [option get . mediumFont Sdr] -pad 1 tixAddBalloon $win.buttons.encmsg Frame [tt "Display the Encryption Security Information."] incr $win.visible pack $win.buttons.encmsg -side left -fill x -expand true } } # label $win.buttons.l -text "Show:" -font $mf # pack $win.buttons.l -side left if {$ldata($aid,uri)!=0} { if {$ifstyle=="norm"} { set str "More\nInformation" set pad 0 } else { set str "More Information" set pad 1 } iconbutton $win.buttons.info -text $str -bitmap www -relief raised \ -borderwidth 1 -command "get_uri $ldata($aid,uri)" \ -font [option get . mediumFont Sdr] -pad $pad tixAddBalloon $win.buttons.info Frame [tt "Click here for more \ information about the session. The information will be in the \ form of a web page. In case of problems with your web browser, \ please choose Preferences in the main session window then \ choose Web"] pack $win.buttons.info -side left -fill x -expand true incr $win.visible } if {$ifstyle=="norm"} { set str "Contact\nDetails" set pad 0 } else { set str "Contact Details" set pad 1 } iconbutton $win.buttons.contact -text $str -bitmap phone -relief raised \ -borderwidth 1 -command "contact $win $aid" \ -font [option get . mediumFont Sdr] -pad $pad tixAddBalloon $win.buttons.contact Frame [tt "Display the name, email address, and phone number of the person who is responsible for this session."] incr $win.visible pack $win.buttons.contact -side left -fill x -expand true # if {($ldata($aid,no_of_times)>1)||($ldata($aid,time0,no_of_rpts)>0)} { # iconbutton $win.buttons.times -text "Detailed times" -bitmap clock -relief raised \ # -borderwidth 1 -command "show_times $win $aid" -font [option get . mediumFont Sdr] # tixAddBalloon $win.buttons.times Button [tt "Display detailed information about when this session is active."] # incr $win.visible # pack $win.buttons.times -side left -fill x -expand true # } if {$ifstyle=="norm"} { iconbutton $win.buttons.tech -text "Media\nDetails" -command \ "popup $aid tech $msgsrc;break" -borderwidth 1 -relief raised \ -bitmap tools -font [option get . mediumFont Sdr] -pad 0 tixAddBalloon $win.buttons.tech Frame [tt "Click here for information \ about the media used in the session and their formats, and to start up the \ media tools individually."] pack $win.buttons.tech -side left -fill x -expand true incr $win.visible } #display the conf multicast address if it's not one per media # if {$ldata($aid,multicast)!=""} { # frame $win.f1 -relief groove -borderwidth 2 # label $win.f1.l -text [tt "Multicast address: "] -font $infofont # label $win.f1.d -text $ldata($aid,multicast) -relief sunken \ # -borderwidth 1 -font $infofont # label $win.f1.l2 -text [tt "ttl:"] -font $infofont # label $win.f1.d2 -text $ldata($aid,ttl) -relief sunken \ # -borderwidth 1 -font $infofont # pack $win.f1.l -side left # pack $win.f1.d -side left # pack $win.f1.l2 -side left # pack $win.f1.d2 -side left # pack $win.f1 -side top -fill x -expand true # } frame $win.media -width 1 -height 1 pack $win.media -side top -fill x -expand true for {set i 0} {$i < $ldata($aid,medianum)} {incr i} { # set fname $win.media.$ldata($aid,$i,media) set fname $win.media.$i frame $fname -borderwidth 2 if {$ldata($aid,medianum) > 1} { iconbutton $fname.l1 -bitmap [get_icon $ldata($aid,$i,media)] -width 10 -text $ldata($aid,$i,media) -relief raised -borderwidth 2\ -command "if {\[start_media \"$aid\" $i start\]} {\ timedmsgpopup \"\[tt \"Please wait...\"\]\" \"the $ldata($aid,$i,media) tool is starting\" 3000}" tixAddBalloon $fname.l1 Frame "Starts the $ldata($aid,$i,media) tool for this session" if {$msgsrc!="advert"} { $fname.l1.workaround configure -state disabled -relief flat } } else { # label $fname.l1 -text [tt "Media:"] -font $infofont label $fname.l1 -bitmap [get_icon $ldata($aid,$i,media)] } # label $fname.d1 -text $ldata($aid,$i,media) -relief sunken -borderwidth 1\ # -font $infofont label $fname.l4 -text [tt "Addr:"] -font $infofont entry $fname.d4 -relief sunken -borderwidth 1\ -width 13 -font $infofont -highlightthickness 0 $fname.d4 insert 0 $ldata($aid,$i,addr) if {$ldata($aid,$i,layers)>1} { $fname.d4 insert end "/$ldata($aid,$i,layers)" } label $fname.l5 -text [tt "TTL:"] -font $infofont entry $fname.d5 -relief sunken -borderwidth 1\ -width 3 -font $infofont -highlightthickness 0 $fname.d5 insert 0 $ldata($aid,$i,ttl) label $fname.l2 -text [tt "Port:"] -font $infofont entry $fname.d2 -relief sunken -borderwidth 1\ -width 5 -font $infofont -highlightthickness 0 $fname.d2 insert 0 $ldata($aid,$i,port) label $fname.l3 -text [tt "Format:"] -font $infofont entry $fname.d3 -relief sunken -borderwidth 1\ -width 5 -font $infofont -highlightthickness 0 $fname.d3 insert 0 [get_fmt_name $ldata($aid,$i,fmt)] label $fname.l7 -text [tt "Proto:"] -font $infofont entry $fname.d7 -relief sunken -borderwidth 1\ -width 5 -font $infofont -highlightthickness 0 $fname.d7 insert 0 [get_proto_name $ldata($aid,$i,proto)] label $fname.l8 -text [tt "Key:"] -font $infofont entry $fname.d8 -relief sunken -borderwidth 1\ -width 25 -font $infofont -highlightthickness 0 tixAddBalloon $fname.d8 Entry [tt "The $ldata($aid,$i,media) encryption key is shown here. If it is blank no encryption is being used."] if { [info exists ldata($aid,$i,mediakey)] && ($ldata($aid,$i,mediakey) != "")} { $fname.d8 insert 0 $ldata($aid,$i,mediakey) } foreach e "$fname.d4 $fname.d5 $fname.d2 $fname.d3 $fname.d7" { bind $e {break} bind $e <2> {break} bind $e <1> {%W selection from @%x;break} } # pack $fname.d1 -side left -expand true -fill x if {$ifstyle=="norm"} { # pack $fname.l1 -side left -fill x -expand true # pack $fname -side left -fill x -expand true } else { pack $fname.l1 -side left pack $fname.l3 -side left pack $fname.d3 -side left pack $fname.l7 -side left pack $fname.d7 -side left pack $fname.l4 -side left pack $fname.d4 -side left pack $fname.l2 -side left pack $fname.d2 -side left pack $fname.l5 -side left pack $fname.d5 -side left pack $fname.l8 -side left pack $fname.d8 -side left if {$ldata($aid,$i,vars) != ""} { label $fname.l6 -text [tt "Vars:"] -font $infofont entry $fname.d6 -relief sunken -borderwidth 1\ -font $infofont -highlightthickness 0 $fname.d6 insert 0 [split $ldata($aid,$i,vars) "\n"] bind $fname.d6 {break} bind $fname.d6 <2> {break} bind $fname.d6 <1> {%W selection from @%x;break} pack $fname.l6 -side left pack $fname.d6 -side left -expand true -fill x } pack $fname -side top -fill x } } if {$ifstyle=="tech"} { label $win.heard -text \ "[tt "Heard from"] $ldata($aid,heardfrom) [tt at] $ldata($aid,theard)" \ -font [option get . infoFont Sdr] pack $win.heard -side top if {$ldata($aid,source)!=$ldata($aid,heardfrom)} { label $win.src -text "[tt "Originally announced from"] $ldata($aid,source)" \ -font [option get . infoFont Sdr] pack $win.src -side top } } frame $win.f3 button $win.f3.dismiss -text [tt "Dismiss"] -relief raised \ -command "set tmp \"$aid,is_popped\";\ highlight_tag $aid popdown;\ set ldata(\$tmp) -1;\ destroy $wname" -highlightthickness 0 tixAddBalloon $win.f3.dismiss Button [tt "Click here to dismiss this window"] if {$ldata($aid,medianum) > 1} { button $win.f3.start -relief raised \ -command "start_all \"$aid\"" -highlightthickness 0 $win.f3.start configure -text [tt "Join"] tixAddBalloon $win.f3.start Button [tt "Start all the media tools for this conference"] } elseif {$ldata($aid,medianum) != 0 } { button $win.f3.start -text [tt "Join"] -relief raised \ -command "start_all \"$aid\"" -highlightthickness 0 tixAddBalloon $win.f3.start Button [tt "Start the media tool for this conference"] } button $win.f3.invite -text [tt "Invite"] -relief raised \ -command "embed_invite \"$aid\" $win" -highlightthickness 0 tixAddBalloon $win.f3.invite Button [tt "Click here to invite someone to join this session"] button $win.f3.record -text [tt "Record"] -relief raised \ -command "record \"$aid\"" -highlightthickness 0 tixAddBalloon $win.f3.record Button [tt "Click here to record the session"] #Is this a session we announced? If so, let us modify it... set username $ldata($aid,creator) set mysess 0 if {([gethostaddr]==$ldata($aid,source)) && \ ([getusername]==$username) && \ ($ldata($aid,trust)=="trusted")} { set mysess 1 button $win.f3.edit -text [tt "Edit"] -relief raised \ -command "new \"$aid\"" -highlightthickness 0 tixAddBalloon $win.f3.edit Button [tt "This is a session you created. Click here to modify the session details"] #note this window gets destroyed from the trace on ldata($aid,session) button $win.f3.delete -text [tt "Delete"] -relief raised \ -command "delete_session \"$aid\"; \ set tmp \"$aid,is_popped\";\ set ldata(\$tmp) -1;\ catch \"destroy $wname\"" -highlightthickness 0 tixAddBalloon $win.f3.delete Button [tt "This is a session you created. Click here to delete the session announcement"] } if {$msgsrc=="advert"} { if {$ldata($aid,medianum) != 0 } { pack $win.f3.start -side left -fill x -expand true pack $win.f3.invite -side left -fill x -expand true pack $win.f3.record -side left -fill x -expand true } if {$mysess==1} { pack $win.f3.edit -side left -fill x -expand true pack $win.f3.delete -side left -fill x -expand true } pack $win.f3.dismiss -side left -fill x -expand true } else { button $win.f3.accept -text [tt "Accept Invitation"] -relief raised \ -highlightthickness 0 -command \ "accept_invite_fix_ui $win $aid;sip_accept_invite $aid" button $win.f3.refuse -text [tt "Reject Invitation"] -relief raised \ -command "destroy $wname;sip_refuse_invite $aid" \ -highlightthickness 0 pack $win.f3.accept -side left -fill x -expand true pack $win.f3.refuse -side left -fill x -expand true } pack $win.f3 -side top -fill x -expand true move_onscreen $wname } proc explain_icon {win txt} { set icon [lindex [$win configure -bitmap] 4] $win configure -bitmap "" -text [tt $txt] set cmd "after 3000 {catch {$win configure -bitmap $icon}}" eval $cmd } proc accept_invite_fix_ui {win aid} { global ldata pack unpack $win.f3.accept pack unpack $win.f3.refuse pack $win.f3.start -side left -fill x -expand true pack $win.f3.record -side left -fill x -expand true pack $win.f3.dismiss -side left -fill x -expand true if {$ldata($aid,medianum)>1} { for {set i 0} {$i < $ldata($aid,medianum)} {incr i} { # set fname $win.media.$ldata($aid,$i,media) set fname $win.media.$i $fname.l1.workaround configure -state normal -relief raised } } } proc popup_update {aid field value} { set win .desc$aid.f catch { case $field in { heard { $win.heard configure -text $value } src { $win.src configure -text $value } name { $win.sn.l configure -text $value } desc { $win.f0.desc configure -state normal $win.f0.desc delete 0.0 end $win.f0.desc insert 0.0 $value $win.f0.desc configure -state disabled highlight_url $win.f0.desc } from { $win.linfo.from configure -text $value } to { $win.linfo.to configure -text $value } } } } proc popup_update_media {aid medianum fmt proto port ttl addr layers mediakey vars} { set fname .desc$aid.f.media.$medianum catch { $fname.d3 delete 0 end $fname.d3 insert 0 [get_fmt_name $fmt] $fname.d7 delete 0 end $fname.d7 insert 0 [get_proto_name $proto] $fname.d2 delete 0 end $fname.d2 insert 0 $port $fname.d5 delete 0 end $fname.d5 insert 0 $ttl $fname.d4 delete 0 end $fname.d4 insert 0 $addr $fname.d8 delete 0 end $fname.d8 insert 0 $mediakey if {$layers>1} { $fname.d4 insert end "/$layers" } if {$vars != ""} { set code 0 catch {set code [$fname.d6 delete 0 end;$fname.d6 insert 0 $vars]} if {$code==0} { set infofont "[option get . infoFont Sdr]" label $fname.l6 -text "Vars:" -font $infofont entry $fname.d6 -relief sunken -borderwidth 1\ -font $infofont $fname.d6 insert 0 $vars bind $fname.d6 {break} bind $fname.d6 <1> {%W selection from @%x;break} bind $fname.d6 <2> {break} pack $fname.l6 -side left pack $fname.d6 -side left -expand true -fill x } } else { $fname.d6 delete 0 end } } } proc sameday {t1 t2} { if {[cropdate $t1] == [cropdate $t2]} { return 1 } else {return 0} } proc croptime {time} { return "[lindex $time 3]" } proc croptz {time} { return "[lindex $time 4]" } proc cropdate {time} { return "[lindex $time 0] [lindex $time 1] [lindex $time 2]" } proc contact {win aid} { global ldata global $win.visible pack forget $win.buttons.contact incr $win.visible -1 if {[set $win.visible]==0} {pack forget $win.buttons} frame $win.cinfo -borderwidth 2 -relief groove set mf [option get . mediumFont Sdr] pack $win.cinfo -side top -fill x -after $win.hidden2 label $win.cinfo.created -text "Created by: $ldata($aid,creator)@$ldata($aid,createaddr)" -font $mf pack $win.cinfo.created -side top if {$ldata($aid,tool)!="unknown"} { label $win.cinfo.tool -font $mf \ -text "Session announced using $ldata($aid,tool)" pack $win.cinfo.tool -after $win.cinfo.created -side top } set i 0 foreach p $ldata($aid,phonelist) { pack [frame $win.cinfo.p$i] -after $win.cinfo.created -side top label $win.cinfo.p$i.icon -bitmap phone pack $win.cinfo.p$i.icon -side left #make this an entry not a label so we can cut from it entry $win.cinfo.p$i.phone -font $mf -relief flat \ -width [string length $p] -highlightthickness 0 $win.cinfo.p$i.phone insert 0 $p bind $win.cinfo.p$i.phone {break} bind $win.cinfo.p$i.phone <1> {%W selection from @%x;break} bind $win.cinfo.p$i.phone <2> {break} pack $win.cinfo.p$i.phone -side left incr i } set i 0 foreach e $ldata($aid,emaillist) { pack [frame $win.cinfo.e$i] -after $win.cinfo.created -side top label $win.cinfo.e$i.icon -bitmap mail pack $win.cinfo.e$i.icon -side left #make this an entry not a label so we can cut from it entry $win.cinfo.e$i.email -font $mf -relief flat \ -width [string length $e] -highlightthickness 0 $win.cinfo.e$i.email insert 0 $e bind $win.cinfo.e$i.email {break} bind $win.cinfo.e$i.email <1> {%W selection from @%x;break} bind $win.cinfo.e$i.email <2> {break} pack $win.cinfo.e$i.email -side left incr i } } proc show_times {win aid} { global lang global $win.visible pack forget $win.buttons.times incr $win.visible -1 if {[set $win.visible]==0} {pack forget $win.buttons} case $lang in { {C En} {show_times_english $win $aid} default {show_times_english $win $aid} } } proc text_times_english {aid} { global ldata set timestr [tt "Session will take place\n"] for {set i 0} {$i<$ldata($aid,no_of_times)} {incr i} { if {$i!=0} { set timestr "$timestr\nand "} if {$ldata($aid,time$i,no_of_rpts)!=0} { for {set r 0} {$r<$ldata($aid,time$i,no_of_rpts)} {incr r} { if {$r!=0} { append timestr "\nand " } set durationstr [get_duration \ [get_duration_ix_by_time $ldata($aid,time$i,duration$r)]] set begintime $ldata($aid,starttime,$i) set fromdate [cropdate $ldata($aid,tfrom,$i)] set todate [cropdate $ldata($aid,tto,$i)] for {set rno 0} {$rno<[llength $ldata($aid,time$i,offset$r)]} {incr rno} { if {$rno!=0} { append timestr "\nand " } case $ldata($aid,time$i,interval$r) in { 86400 { set rtime [clock format \ [expr $begintime+\ [lindex $ldata($aid,time$i,offset$r) $rno]] \ -format {%H:%M %Z}] set timestr "${timestr}daily at $rtime for $durationstr between $fromdate and $todate" } 604800 { set dayofweek "" set offsets $ldata($aid,time$i,offset$r) set rno [llength $offsets] foreach offset $offsets { if {$offset==[lindex $offsets 0]} { set pad "" } elseif {$offset==[lindex $offsets \ [expr [llength $offsets]-1]]} { set pad " and " } else {set pad ", "} set dayofweek [format "%s%s%s" $dayofweek $pad\ [lindex [gettime \ [expr $ldata($aid,starttime,$i) + $offset]] 8]] } set rtime [clock format $begintime -format {%H:%M %Z}] set timestr "${timestr}weekly at $rtime on $dayofweek for $durationstr\nfrom $fromdate to $todate" } 1209600 { set dayofweek [lindex [gettime $ldata($aid,starttime,$i)] 8] set rtime [clock format \ [expr $begintime+\ [lindex $ldata($aid,time$i,offset$r) $rno]] \ -format {%H:%M %Z}] set timestr "${timestr}every 2 weeks at $rtime on $dayofweek for $durationstr\nfrom $fromdate to $todate" } default { set dayofweek [lindex [gettime $ldata($aid,starttime,$i)] 8] set secs $ldata($aid,time$i,interval$r) set interval {} set seperator {} set int(604800) "weeks" set int(86400) "days" set int(3600) "hours" set int(60) "minutes" set int(1) "seconds" foreach ix {604800 86400 3600 60 1} { if {$secs > $ix} { append interval $seperator "[expr $secs/$ix] $int($ix)" set seperator ", " set secs [expr $secs % $ix] } } set rtime [clock format \ [expr $begintime+\ [lindex $ldata($aid,time$i,offset$r) $rno]] \ -format {%H:%M %Z}] set timestr "${timestr}every $interval starting at $rtime on $dayofweek $fromdate for $durationstr until $todate" } } #here } } } else { if {[sameday $ldata($aid,tfrom,$i) $ldata($aid,tto,$i)]} { set timestr [format "%sfrom %s to %s %s on %s" $timestr\ [croptime $ldata($aid,tfrom,$i)]\ [croptime $ldata($aid,tto,$i)]\ [croptz $ldata($aid,tto,$i)]\ [cropdate $ldata($aid,tfrom,$i)]] } else { set timestr [format "%sfrom %s %s to %s" $timestr\ [cropdate $ldata($aid,tfrom,$i)]\ [croptime $ldata($aid,tfrom,$i)]\ $ldata($aid,tto,$i)] } } } # set timestr "$timestr \nfrom [cropdate $ldata($aid,tfrom)] [croptime $ldata($aid,tfrom)] to $ldata($aid,tto)" return $timestr } proc show_times_english {win aid} { global ldata set timestr [tt "Session will take place\n"] pack [message $win.msg -width 400 -justify center -borderwidth 2 -relief groove -font [option get . mediumFont Sdr]] -after $win.hidden1 -side top -fill x -expand true $win.msg configure -text [text_times_english $aid] } #proc text_wrap {t width} { # set rt "" # regsub -all "( *)(\n)( *)" $t " " t # if {[string length $t]<=$width} {return $t} # while {[string length $t]>$width} { # set thisline [string range [string trimleft $t] 0 [expr $width-1]] # # set eol [string last " " $thisline] # if {$eol<=0} {set eol [string last "\n" $thisline]} # if {$eol>0} { # if {$rt!=""} { set rt "$rt\n[string range $t 0 $eol]" # } else {set rt [string range $t 0 $eol]} # set t [string trimleft [string range $t [expr $eol+1] end]] # } else { # set eol [string first " " $t] # if {$eol<=0} {set eol [string last "\n" $thisline]} # if {$eol>0} { # set rt "$rt\n[string range $t 0 $eol]" # set t [string trimleft [string range $t [expr $eol+1] end]] # # } else { # set rt "$rt\n$t" # set t "" # } # } # } # set rt "$rt\n$t" # return $rt #} proc delete_session {aid} { global ldata ui_stop_session_ad $aid set ldata($aid,endtime) 1 timeout_expired_sessions msgpopup [tt "Session Deleted"] [tt "The session will no longer be announced, but may take some time before it is deleted from everyone's sdr display"] after 1000 write_cache } proc record {aid} { global ldata catch {destroy .record} toplevel .record wm title .record "Sdr: [tt "Record Session"]" frame .record.f -borderwidth 2 -relief groove label .record.f.l -text $ldata($aid,session) pack .record.f.l -side top frame .record.f.f0 -relief sunken -borderwidth 2 listbox .record.f.f0.lb -width 50 -height 10 \ -yscroll ".record.f.f0.sb set" \ -selectforeground [resource activeForeground] \ -selectbackground [resource activeBackground] \ -highlightthickness 0 scrollbar .record.f.f0.sb -command ".record.f.f0.lb yview" \ -background [resource scrollbarForeground] \ -troughcolor [resource scrollbarBackground] \ -highlightthickness 0 #TBD # -foreground [option get . scrollbarForeground Sdr] \ # -activeforeground [option get . scrollbarActiveForeground Sdr] foreach i [exec ls -a] { .record.f.f0.lb insert end $i } pack .record.f.f0.lb -side left pack .record.f.f0.sb -side left -fill y pack .record.f.f0 -side top label .record.f.l2 -text [tt "File to save to:"] pack .record.f.l2 -side top -anchor w entry .record.f.entry -width 50 -relief sunken bind .record.f.entry "start_record \$rectime \[.record.f.entry get\] \"$aid\" record" .record.f.entry insert 0 [pwd] bind .record.f.f0.lb <1> {%W selection set [%W nearest %y];\ .record.f.entry delete 0 end;\ .record.f.entry insert 0 "[pwd]/[lindex [selection get] 0]"} bind .record.f.f0.lb "start_record \$rectime \[lindex \[selection get\] 0\] \"$aid\" record" pack .record.f.entry -side top -anchor w -fill x -expand true frame .record.f.f1 label .record.f.f1.l -text [tt "Start Recording:"] global rectime set rectime now radiobutton .record.f.f1.b1 -text "now" -variable rectime \ -value [tt "now"] \ -highlightthickness 0 \ -relief flat radiobutton .record.f.f1.b2 -text [tt "when session starts"] \ -highlightthickness 0 \ -variable rectime -value "start" -relief flat if {$ldata($aid,starttime)<[gettimeofday]} { .record.f.f1.b2 configure -state disabled .record.f.f1.b2 configure -text [tt "session has started"] } global record catch {unset record} for {set i 0} {$i < $ldata($aid,medianum)} {incr i} { set media $ldata($aid,$i,media) set record($media) 1 } if {$ldata($aid,medianum)>1} { frame .record.f.f3 -relief groove -borderwidth 2 for {set i 0} {$i < $ldata($aid,medianum)} {incr i} { set media $ldata($aid,$i,media) checkbutton .record.f.f3.b$i -text "[tt Record] $media" \ -variable record($media) pack .record.f.f3.b$i -side top -anchor w -fill x -expand true } pack .record.f.f3 -side top -fill x } pack .record.f.f1.l -side top -anchor w pack .record.f.f1.b1 -side top -padx 10 -anchor w pack .record.f.f1.b2 -side top -padx 10 -anchor w pack .record.f.f1 -side top -fill x frame .record.f.f2 -relief groove -borderwidth 2 button .record.f.f2.rec -text [tt Record] -relief raised \ -command "start_record \$rectime \[.record.f.entry get\] \"$aid\" record" button .record.f.f2.dismiss -text [tt Dismiss] -relief raised \ -command {destroy .record} -highlightthickness 0 pack .record.f.f2.rec -side left -fill x -expand true pack .record.f.f2.dismiss -side left -fill x -expand true pack .record.f.f2 -side top -fill x pack .record.f -side top move_onscreen .record } proc start_record {time file aid rname} { global ldata if {[file isdirectory $file]} { .record.f.f0.lb delete 0 end cd $file foreach i [exec ls -a] { .record.f.f0.lb insert end $i } .record.f.entry delete 0 end .record.f.entry insert 0 [pwd] msgpopup [tt "Error"] [tt "Please give a filename in addition to a directory"] } else { if {$time=="now"} { timedmsgpopup [tt "Starting Recording"] "" 3000 start_recorder $aid $file $rname destroy .record } else { timedmsgpopup [tt "Recording Prepared"] \ [tt "The recording will start at $ldata($aid,tfrom)"] 6000 msgpopup [tt "Error"] [tt "feature is not yet implemented - sorry"] destroy .record } } } proc start_recorder {aid fname rname} { global ldata $rname set file [open "|record_session $fname" w] set source [dotted_decimal_to_decimal $ldata($aid,source)] set heardfrom [dotted_decimal_to_decimal $ldata($aid,heardfrom)] set lastheard $ldata($aid,lastheard) set sap_addr $ldata($aid,sap_addr) set sap_port $ldata($aid,sap_port) set trust $ldata($aid,trust) # XXX there should be a subroutine which returns an n= line puts $file "n=$source $heardfrom $lastheard $sap_addr $sap_port $trust" puts $file [make_session $aid $rname] close $file } proc get_uri {uri} { global webtype webclient case $webtype { sendmosaic { putlogfile "Sending to Browser" exec xm $uri & } startmosaic { putlogfile "Starting $webclient" exec $webclient $uri & } builtin { webdisp $uri } } } proc stuff_mosaic {} { global webtype webclient if { [catch {selection get} text] == 0 } { get_uri $text } } proc preferences2 {} { global showwhich balloonHelp binder_tags prefprocs catch {destroy .prefs} toplevel .prefs wm title .prefs "Sdr: Preferences" posn_win .prefs frame .prefs.f3 -relief groove -borderwidth 2 label .prefs.f3.l -text [tt "Help mode:"] global balloonHelp checkbutton .prefs.f3.mode -text [tt "Balloon Help"] \ -highlightthickness 0 \ -variable balloonHelp -command {set_balloon_help $balloonHelp}\ -onvalue 1 -offvalue 0 -relief flat tixAddBalloon .prefs.f3.mode Button [tt "Turn Balloon Help on and off"] hlfocus .prefs.f3.mode pack .prefs.f3.l -side left -anchor w pack .prefs.f3.mode -side left -anchor w pack .prefs.f3 -side top -anchor w -fill x -expand true frame .prefs.f0 pack .prefs.f0 -side top canvas .prefs.f0.c -width 600 -height 300 #-background [option get . prefsBackground Sdr] pack .prefs.f0.c -side top set xpos 20 foreach pref $prefprocs { set wname ".prefs.f0.c.$pref" pref_$pref copyin set bname [pref_$pref create $wname 580 200] set balloon [pref_$pref balloon] set xpos \ [add_binder_tag $pref .prefs.f0.c $xpos $bname $balloon $wname] } bind .prefs.f3.mode "focus $binder_tags(show,button)" post_binder .prefs.f0.c show label .prefs.help -relief raised -borderwidth 1 \ -font [option get . infoFont Sdr] pack .prefs.help -side top -fill x -expand true frame .prefs.f1 button .prefs.f1.cancel -text [tt "Cancel"] -command {destroy .prefs} tixAddBalloon .prefs.f1.cancel Button [tt "Discard the changes you've made"] pack .prefs.f1.cancel -side left -fill x -expand true button .prefs.f1.ok -text [tt "Apply Preferences"] -command {\ allprefprocs copyout;\ reshow_sessions $showwhich;\ catch {destroy .ps};\ destroy .prefs} tixAddBalloon .prefs.f1.ok Button [tt "Apply the changes you've made"] pack .prefs.f1.ok -side left -fill x -expand true button .prefs.f1.save -text [tt "Save & Apply Preferences"] -command {\ allprefprocs copyout;\ reshow_sessions $showwhich;\ save_prefs;\ catch {destroy .ps};\ destroy .prefs} tixAddBalloon .prefs.f1.save Button [tt "Apply the changes you've made and also save them for next time you start up sdr"] pack .prefs.f1.save -side left -fill x -expand true pack .prefs.f1 -side top -fill x -expand true move_onscreen .prefs log "showing preferences at [getreadabletime]" } proc bind_help {win str} { global last_help bind $win "prefs_help \"$str\"" bind $win "after 1000 \ {if {\[set last_help\]==\"$str\"} { prefs_help \"\"}}" } proc prefs_help {str} { global last_help catch {.prefs.help configure -text $str} set last_help $str } proc allprefprocs {what {arg2 {}}} { global prefprocs foreach i $prefprocs { catch { pref_$i $what $arg2 } } debug "allprefprocs $what .. done" } set binder_taglist {} set binder_winlist {} proc add_binder_tag {tag canv xpos txt balloon win} { global font binder_taglist binder_winlist binder_tags set wth [expr [string length $txt] * 8] button $canv.b$xpos -text $txt -relief raised -borderwidth 1\ -highlightthickness 0 tixAddBalloon $canv.b$xpos Button $balloon bind $canv.b$xpos "focus $win" hlfocus $canv.b$xpos frame $canv.h$xpos -width [expr [winfo reqwidth $canv.b$xpos]+4] -height 5 $canv addtag b$xpos withtag \ [$canv create window $xpos 5 -window $canv.b$xpos -anchor nw] set binder_tags($tag,x) $xpos set binder_tags($tag,win) $win set binder_tags($tag,hack) $canv.h$xpos set binder_tags($tag,button) $canv.b$xpos set binder_tags($tag,w) w$xpos set binder_tags($tag,h) h$xpos set binder_tags($tag,b) b$xpos $canv.b$xpos configure -command "post_binder $canv $tag" set binder_taglist "$binder_taglist $canv.b$xpos" set binder_winlist "$binder_winlist w$xpos h$xpos" return [expr $xpos+[winfo reqwidth $canv.b$xpos]+10] } proc post_binder {canv tag} { global binder_tags lower_binder_tags $canv $canv addtag $binder_tags($tag,w) withtag \ [$canv create window 10 \ [expr [winfo reqheight $binder_tags($tag,button)]+5]\ -window $binder_tags($tag,win) -anchor nw] $canv addtag $binder_tags($tag,h) withtag \ [$canv create window [expr $binder_tags($tag,x)+0] \ [expr [winfo reqheight $binder_tags($tag,button)]+5]\ -window $binder_tags($tag,hack) -anchor nw] $binder_tags($tag,button) configure -borderwidth 3 $canv raise $binder_tags($tag,h) $binder_tags($tag,b) } proc lower_binder_tags {canv} { global binder_taglist binder_winlist foreach tag $binder_taglist { $tag configure -borderwidth 1 } foreach win $binder_winlist { $canv delete $win } } # Variables: # prefs(show_showwhich) is a copy of $showwhich # prefs(show_aids) is a copy of the aids in $fullix; this is private to # the preferences routine so that added sessions don't make things confusing # prefs(show_aid_$aid) is a copy of ldata($aid,vstate) # proc pref_show {cmd {arg1 {}} {arg2 {}} {arg3 {}}} { global showwhich showwhichfilter filters prefs fullix fullnumitems ldata switch $cmd { copyin { set prefs(show_showwhich) $showwhich foreach filter [array names showwhichfilter] { set prefs(show_showwhichfilter,$filter) \ $showwhichfilter($filter) } foreach i [array names prefs "show_aid_*"] { unset prefs($i) } set prefs(show_aids) {} for {set i 0} {$i < $fullnumitems} {incr i} { set aid $fullix($i) lappend prefs(show_aids) $aid set prefs(show_aid_$aid) $ldata($aid,vstate) } } copyout { set showwhich $prefs(show_showwhich) foreach tag [array names prefs] { set lst [split $tag ","] if {[lindex $lst 0]==\ "show_showwhichfilter"} { set showwhichfilter([lindex $lst 1]) \ $prefs($tag) } } foreach aid $prefs(show_aids) { set ldata($aid,vstate) $prefs(show_aid_$aid) } } defaults { foreach filter $filters { set prefs(show_showwhichfilter,$filter) 1 } set prefs(show_showwhich) all set prefs(show_aids) {} for {set i 0} {$i < $fullnumitems} {incr i} { set aid $fullix($i) lappend prefs(show_aids) $aid set prefs(show_aid_$aid) 1 } } create { select_show_sess $arg1 $arg2 $arg3 return "Sessions" } balloon { return "Select the sessions you would like listed in the main session window" } save { puts $arg1 [list set showwhich $showwhich] foreach filter [array names showwhichfilter] { puts $arg1 [list set showwhichfilter($filter) \ $showwhichfilter($filter)] } for {set i 0} {$i < $fullnumitems} {incr i} { set aid $fullix($i) if {$ldata($aid,vstate)==0} { puts $arg1 "set t $aid; # $ldata($aid,session)" puts $arg1 {set ldata($t,vstate) 0} } } } } } set filters "" proc select_show_sess {win width height} { global prefs showwhichfilter filters frame $win -relief raised -borderwidth 3 frame $win.setw -borderwidth 0 -height 1 -width $width pack $win.setw -side top frame $win.f pack $win.f -side top -fill x -expand true -pady 5 frame $win.f.l pack $win.f.l -side left -fill x -anchor n -expand true frame $win.f.r pack $win.f.r -side right -anchor n frame $win.f.l.f -borderwidth 2 -relief groove pack $win.f.l.f -side top -anchor n -ipadx 10 -ipady 10 label $win.f.l.f.l -text "Show which sessions:" pack $win.f.l.f.l -side top -pady 5 #yeuch - hate making this global radiobutton $win.f.l.f.r1 -text [tt "all sessions"] \ -highlightthickness 0 -command "pref_sess_enable $win.f.r"\ -variable prefs(show_showwhich) -value all -relief flat bind_help $win.f.l.f.r1 [tt "Select this to show all the currently advertised sessions in the main sdr window"] tixAddBalloon $win.f.l.f.r1 Button [tt "Select this to show all the currently advertised sessions"] pack $win.f.l.f.r1 -side top -anchor w -pady 5 radiobutton $win.f.l.f.r2 -text [tt "preferred sessions"] \ -highlightthickness 0 -command "pref_sess_enable $win.f.r"\ -variable prefs(show_showwhich) -value pref -relief flat bind_help $win.f.l.f.r2 [tt "Select this to show only sessions you chose, then select the sessions by clicking on them in this window."] tixAddBalloon $win.f.l.f.r2 Button [tt "Select this to show only the sessions you've chosen."] pack $win.f.l.f.r2 -side top -anchor w -pady 5 radiobutton $win.f.l.f.r3 -text [tt "current sessions"] \ -highlightthickness 0 -command "pref_sess_enable $win.f.r"\ -variable prefs(show_showwhich) -value current -relief flat bind_help $win.f.l.f.r3 [tt "Select this to show only sessions that are currently taking place"] tixAddBalloon $win.f.l.f.r3 Button [tt "Select this to show only sessions that are currently taking place."] pack $win.f.l.f.r3 -side top -anchor w -pady 5 radiobutton $win.f.l.f.r4 -text [tt "future sessions"] \ -highlightthickness 0 -command "pref_sess_enable $win.f.r"\ -variable prefs(show_showwhich) -value future -relief flat bind_help $win.f.l.f.r4 [tt "Select this to show only future sessions in the main sdr window"] tixAddBalloon $win.f.l.f.r4 Button [tt "Select this to show only future sessions"] pack $win.f.l.f.r4 -side top -anchor w -pady 5 label $win.f.l.f.l2 -text "Additional filters:" pack $win.f.l.f.l2 -side top -pady 5 checkbutton $win.f.l.f.c1 -text "Hide test sessions" \ -variable prefs(show_showwhichfilter,test) -relief flat \ -highlightthickness 0 #extend the list of filters lappend filters test pack $win.f.l.f.c1 -side top -anchor w -pady 5 message $win.f.l.msg -aspect 500 -text "" pack $win.f.l.msg -side top uplevel trace variable showwhich w "\"set_showmsg $win\"" hlfocus $win.f.l.f.r1 hlfocus $win.f.l.f.r2 hlfocus $win.f.l.f.r3 hlfocus $win.f.l.f.r4 # pack $win.f.l.f.mod -side top -anchor w pref_sessions $win.f.r pref_sess_enable $win.f.r frame $win.f2 -borderwidth 0 -relief flat -width 1 -height \ [expr $height - [winfo reqheight $win]] pack $win.f2 -side top } proc set_showmsg {win args} { global showwhich if {[winfo exists $win.f.l.msg]} { if {$showwhich == "pref"} { $win.f.l.msg configure -text "Select the sessions you wish to be visible." } else { $win.f.l.msg configure -text "" } } } proc pref_web {cmd {arg1 {}} {arg2 {}} {arg3 {}}} { global prefs webproxy webclient webtype switch $cmd { copyin { set prefs(web_webproxy) $webproxy set prefs(web_webclient) $webclient set prefs(web_webtype) $webtype } copyout { set webproxy $prefs(web_webproxy) set webclient $prefs(web_webclient) set webtype $prefs(web_webtype) } defaults { set prefs(web_webproxy) {} set prefs(web_webclient) Mosaic set prefs(web_webtype) builtin } create { select_show_web $arg1 $arg2 $arg3 return "Web" } balloon { return "Select the way you would like to access web pages" } save { puts $arg1 [list set webtype $webtype] puts $arg1 [list set webclient $webclient] puts $arg1 [list set webproxy $webproxy] } } } proc select_show_web {win width height} { global prefs frame $win -borderwidth 3 -relief raised frame $win.setw -borderwidth 0 -height 1 -width $width pack $win.setw -side top frame $win.f -borderwidth 2 -relief groove pack $win.f -side top -anchor n -pady 5 -ipadx 10 -ipady 10 label $win.f.l -text "Web Links:" radiobutton $win.f.r1 -text [tt "Use web browser already running"] \ -highlightthickness 0 \ -variable prefs(web_webtype) -value sendmosaic -relief flat \ -command {msgpopup [tt "Note..."] [tt "this works with Mosaic and Netscape, not other browsers - you need the xm script"]} bind_help $win.f.r1 [tt "Select this to send URLs to a copy of netscape or Mosaic already running on your machine"] frame $win.f.f radiobutton $win.f.f.r2 -text [tt "Start web browser"] \ -highlightthickness 0 \ -variable prefs(web_webtype) -value startmosaic -relief flat bind_help $win.f.f.r2 [tt "Select this to start a new copy of the web browser for each URL."] entry $win.f.f.wwwname -width 10 -relief sunken -background [option get . entryBackground Sdr] -textvariable prefs(web_webclient) frame $win.f.f2 radiobutton $win.f.f2.r4 -text [tt "Use sdr's built in web browser"] \ -highlightthickness 0 \ -variable prefs(web_webtype) -value builtin -relief flat bind_help $win.f.f2.r4 [tt "Select this to use sdr's built in web browser. This won't use additional colours, so is recommended on 8 bit displays"] frame $win.f.f2.f label $win.f.f2.f.l1 -text [tt " Proxy:"] label $win.f.f2.f.l2 -text [tt "in the form \"host:port\""] \ -font [option get . infoFont Sdr] entry $win.f.f2.f.wwwproxy -width 25 -relief sunken -background [option get . entryBackground Sdr] -textvariable prefs(web_webproxy) bind_help $win.f.f2.f.wwwproxy [tt "Enter your web proxy in the form ``host:port''. This is optional."] tixAddBalloon $win.f.f2 Frame [tt "Enter your web proxy in the form \"host:port\"."] radiobutton $win.f.r3 -text [tt "Add URL to clipboard"] \ -highlightthickness 0 \ -variable prefs(web_webtype) -value cutbuffer -relief flat bind_help $win.f.r3 [tt "Select this to only copy URLs to the clipboard"] hlfocus $win.f.r1 hlfocus $win.f.f.r2 hlfocus $win.f.f2.r4 hlfocus $win.f.r3 pack $win.f.l -side top -pady 5 pack $win.f.r1 -side top -anchor w -pady 5 pack $win.f.f -side top -anchor w -pady 5 pack $win.f.f.r2 -side left -anchor w -pady 5 pack $win.f.f2 -side top -anchor w -pady 5 pack $win.f.f2.r4 -side top -anchor w -pady 5 pack $win.f.f2.f -side top pack $win.f.f2.f.l1 -side left pack $win.f.f2.f.l2 -side left pack $win.f.f2.f.wwwproxy -side left pack $win.f.r3 -side top -anchor w -pady 5 pack $win.f.f.wwwname -side right frame $win.f3 -borderwidth 0 -relief flat -width 1 -height \ [expr $height - [winfo reqheight $win]] pack $win.f3 -side top } proc pref_ifstyle {cmd {arg1 {}} {arg2 {}} {arg3 {}}} { global prefs ifstyle showwhich switch $cmd { copyin { set prefs(ifstyle_create) $ifstyle(create) set prefs(ifstyle_view) $ifstyle(view) set prefs(ifstyle_labels) $ifstyle(labels) set prefs(ifstyle_list) $ifstyle(list) set prefs(ifstyle_order) $ifstyle(order) } copyout { set ifstyle(create) $prefs(ifstyle_create) set ifstyle(view) $prefs(ifstyle_view) if {[info exists ifstyle(labels)]\ &&($ifstyle(labels)!=$prefs(ifstyle_labels))} { set ifstyle(labels) $prefs(ifstyle_labels) build_interface again } set ifstyle(labels) $prefs(ifstyle_labels) if {([info exists ifstyle(list)]\ &&($ifstyle(list)!=$prefs(ifstyle_list)))\ ||([info exists ifstyle(order)]\ &&($ifstyle(order)!=$prefs(ifstyle_order)))} { set ifstyle(list) $prefs(ifstyle_list) set ifstyle(order) $prefs(ifstyle_order) resort_sessions } else { set ifstyle(order) $prefs(ifstyle_order) set ifstyle(list) $prefs(ifstyle_list) } } defaults { set prefs(ifstyle_create) norm set prefs(ifstyle_view) tech set prefs(ifstyle_labels) short set prefs(ifstyle_list) logo set prefs(ifstyle_order) alphabetic } create { select_if_style $arg1 $arg2 $arg3 return "Interface" } balloon { return "Select whether you want a normal interface or a technical interface when creating and viewing sessions" } save { puts $arg1 [list set ifstyle(create) $ifstyle(create)] puts $arg1 [list set ifstyle(view) $ifstyle(view)] puts $arg1 [list set ifstyle(labels) $ifstyle(labels)] puts $arg1 [list set ifstyle(list) $ifstyle(list)] puts $arg1 [list set ifstyle(order) $ifstyle(order)] } } } proc select_if_style {win width height} { frame $win -borderwidth 3 -relief raised frame $win.setw -borderwidth 0 -height 1 -width $width pack $win.setw -side top label $win.l -text "Interface Style" pack $win.l -side top frame $win.f pack $win.f -side top -expand true -fill x frame $win.f.l -relief groove -borderwidth 2 pack $win.f.l -side left -fill y -expand true label $win.f.l.l -text "Create Session:" pack $win.f.l.l -side top -anchor w radiobutton $win.f.l.a -text "Normal Interface" \ -highlightthickness 0 \ -variable prefs(ifstyle_create) -value norm bind_help $win.f.l.a [tt "Select this to use the normal interface to create new sessions"] pack $win.f.l.a -side top -anchor w radiobutton $win.f.l.b -text "Technical Interface" \ -highlightthickness 0 \ -variable prefs(ifstyle_create) -value tech bind_help $win.f.l.b [tt "Select this to use the more complicated technical interface to create new sessions"] pack $win.f.l.b -side top -anchor w frame $win.f.m -relief groove -borderwidth 2 pack $win.f.m -side left -fill y -expand true label $win.f.m.l -text "View Session:" pack $win.f.m.l -side top -anchor w radiobutton $win.f.m.a -text "Normal Interface" \ -highlightthickness 0 \ -variable prefs(ifstyle_view) -value norm bind_help $win.f.m.a [tt "Select this to use the normal interface to view the details of sessions"] pack $win.f.m.a -side top -anchor w radiobutton $win.f.m.b -text "Technical Interface" \ -highlightthickness 0 \ -variable prefs(ifstyle_view) -value tech bind_help $win.f.m.b [tt "Select this to use the more complicated technical interface to view the details of sessions"] pack $win.f.m.b -side top -anchor w frame $win.f.r -relief groove -borderwidth 2 pack $win.f.r -side left -fill y -expand true label $win.f.r.l -text "Label Detail:" pack $win.f.r.l -side top -anchor w radiobutton $win.f.r.a -text "Long labels (beginnner mode)" \ -highlightthickness 0 \ -variable prefs(ifstyle_labels) -value long bind_help $win.f.r.a [tt "Select this to obtain long labels and additional explanations as to what to do"] pack $win.f.r.a -side top -anchor w radiobutton $win.f.r.b -text "Short Labels (expert mode)" \ -highlightthickness 0 \ -variable prefs(ifstyle_labels) -value short bind_help $win.f.r.b [tt "Select this to obtain short labels and an interface less cluttered with help messages"] pack $win.f.r.b -side top -anchor w frame $win.f2 frame $win.f2.r -relief groove -borderwidth 2 pack $win.f2.r -side left -fill y -expand true label $win.f2.r.l -text "Session Listing:" pack $win.f2.r.l -side top -anchor w radiobutton $win.f2.r.r1 -text "List Alphabetically" \ -variable prefs(ifstyle_order) -value alphabetic \ -highlightthickness 0 pack $win.f2.r.r1 -side top -anchor w radiobutton $win.f2.r.r2 -text "List by Session Type" \ -variable prefs(ifstyle_order) -value type \ -highlightthickness 0 pack $win.f2.r.r2 -side top -anchor w checkbutton $win.f2.r.b -text "Show session type" \ -variable prefs(ifstyle_list) -onvalue logo -offvalue normal \ -highlightthickness 0 pack $win.f2.r.b -side top pack $win.f2 -side top -anchor w -pady 10 -padx 15 frame $win.f3 -borderwidth 0 -relief flat -width 1 -height \ [expr $height - [winfo reqheight $win]] hlfocus $win.f.l.a hlfocus $win.f.l.b hlfocus $win.f.m.a hlfocus $win.f.m.b hlfocus $win.f.r.a hlfocus $win.f.r.b pack $win.f3 -side top } proc pref_pers {cmd {arg1 {}} {arg2 {}} {arg3 {}}} { global prefs yourname youremail yourphone youralias sip_server_url switch $cmd { copyin { set prefs(pers_name) $yourname set prefs(pers_email) $youremail set prefs(pers_phone) $yourphone set prefs(pers_alias) $youralias set prefs(pers_sipserv) $sip_server_url } copyout { set yourname $prefs(pers_name) set youremail $prefs(pers_email) set yourphone $prefs(pers_phone) set youralias $prefs(pers_alias) set sip_server_url $prefs(pers_sipserv) } defaults { # XXX this is *wrong* # if there is going to be a UI "defaults" button set prefs(pers_name) {} set prefs(pers_email) {} set prefs(pers_phone) {} set prefs(pers_alias) {} set prefs(pers_sipserv) {} } create { select_your_info $arg1 $arg2 $arg3 return "You" } balloon { return "Enter your personal details here. They will be added to sessions you create so people can contact you if there is a problem." } save { puts $arg1 [list set yourname $yourname] puts $arg1 [list set youremail $youremail] puts $arg1 [list set yourphone $yourphone] puts $arg1 [list set youralias $youralias] puts $arg1 [list set sip_server_url $sip_server_url] } } } proc select_your_info {win width height} { global prefs frame $win -borderwidth 3 -relief raised frame $win.setw -borderwidth 0 -height 1 -width $width pack $win.setw -side top label $win.l -text [tt "Your Name, Email Address and Phone Number"] bind $win.l {prefs_help [tt "These will be added to sessions you create so people can contact you if there is a problem"]} bind $win.l {prefs_help ""} pack $win.l -side top frame $win.f pack $win.f -side top frame $win.f.n pack $win.f.n -side top -fill x -expand true -pady 5 label $win.f.n.l -text [tt "Name:"] pack $win.f.n.l -side left entry $win.f.n.e -width 30 -relief sunken -background [option get . entryBackground Sdr] -textvariable prefs(pers_name) pack $win.f.n.e -side right frame $win.f.e pack $win.f.e -side top -fill x -expand true -pady 5 label $win.f.e.l -text [tt "Email:"] pack $win.f.e.l -side left entry $win.f.e.e -width 30 -relief sunken -background [option get . entryBackground Sdr] -textvariable prefs(pers_email) pack $win.f.e.e -side right frame $win.f.p pack $win.f.p -side top -fill x -expand true -pady 5 label $win.f.p.l -text [tt "Phone:"] pack $win.f.p.l -side left entry $win.f.p.e -width 30 -relief sunken -background [option get . entryBackground Sdr] -textvariable prefs(pers_phone) pack $win.f.p.e -side right message $win.f.sipa -aspect 400 -font [option get . infoFont Sdr] -text \ "A SIP alias is a name people can put in a session invitation to call you. Normally they will use your username, but if you want sdr to answer calls addressed to a more human-readable name, you can add it here. You cannot add another valid username." pack $win.f.sipa -side top frame $win.f.a pack $win.f.a -side top -fill x -expand true -pady 5 label $win.f.a.l -text [tt "SIP Alias:"] pack $win.f.a.l -side left entry $win.f.a.e -width 30 -relief sunken -background [option get . entryBackground Sdr] -textvariable prefs(pers_alias) pack $win.f.a.e -side right frame $win.f.ss pack $win.f.ss -side top -fill x -expand true -pady 5 label $win.f.ss.l -text [tt "SIP Server URL:"] pack $win.f.ss.l -side left entry $win.f.ss.e -width 30 -relief sunken -background [option get . entryBackground Sdr] -textvariable prefs(pers_sipserv) pack $win.f.ss.e -side right frame $win.f2 -borderwidth 0 -relief flat -width 1 -height \ [expr $height - [winfo reqheight $win]] pack $win.f2 -side top } proc pref_people {cmd {arg1 {}} {arg2 {}} {arg3 {}}} { global prefs switch $cmd { copyin { address_book_copyin } copyout { address_book_copyout } defaults { } create { select_address_book $arg1 $arg2 $arg3 return "People" } balloon { return "Use the address book to store the addresses of people you call frequently." } save { save_address_book $arg1 } } } proc preferences {} { global showwhich webtype webclient webproxy balloonHelp catch {destroy .prefs} toplevel .prefs wm title .prefs "Sdr: Preferences" posn_win .prefs frame .prefs.f3 -relief groove -borderwidth 2 label .prefs.f3.l -text [tt "Help mode:"] global balloonHelp checkbutton .prefs.f3.mode -text [tt "Balloon Help"] \ -highlightthickness 0 \ -variable balloonHelp -command {set_balloon_help $balloonHelp}\ -onvalue 1 -offvalue 0 -relief flat tixAddBalloon .prefs.f3.mode Button [tt "Turn Balloon Help on and off"] pack .prefs.f3.l -side left -anchor w pack .prefs.f3.mode -side left -anchor w pack .prefs.f3 -side top -anchor w -fill x -expand true frame .prefs.f0 frame .prefs.f0.f0 -relief groove -borderwidth 2 label .prefs.f0.f0.l -text "Show which sessions:" #yeuch - hate making this global radiobutton .prefs.f0.f0.r1 -text [tt "all sessions"] \ -highlightthickness 0 \ -variable showwhich -value all -relief flat tixAddBalloon .prefs.f0.f0.r1 Button [tt "Select this to show all the currently advertised sessions"] radiobutton .prefs.f0.f0.r2 -text [tt "preferred sessions"] \ -highlightthickness 0 \ -variable showwhich -value pref -relief flat tixAddBalloon .prefs.f0.f0.r2 Button [tt "Select this to show only the sessions you've chosen. Press \"Specify Preferred Sessions\" to view your chosen sessions"] radiobutton .prefs.f0.f0.r3 -text [tt "current sessions"] \ -highlightthickness 0 \ -variable showwhich -value current -relief flat tixAddBalloon .prefs.f0.f0.r3 Button [tt "Select this to show only sessions that are currently active"] radiobutton .prefs.f0.f0.r4 -text [tt "future sessions"] \ -highlightthickness 0 \ -variable showwhich -value future -relief flat tixAddBalloon .prefs.f0.f0.r4 Button [tt "Select this to show only future sessions"] button .prefs.f0.f0.mod -text [tt "Specify Preferred Sessions"] \ -command "pref_sessions" tixAddBalloon .prefs.f0.f0.mod Button [tt "Press to view or change your chosen list of sessions"] pack .prefs.f0.f0.l -side top pack .prefs.f0.f0.r1 -side top -anchor w pack .prefs.f0.f0.r2 -side top -anchor w pack .prefs.f0.f0.r3 -side top -anchor w pack .prefs.f0.f0.r4 -side top -anchor w pack .prefs.f0.f0.mod -side top -anchor w pack .prefs.f0.f0 -side left -anchor n frame .prefs.f0.f1 -relief groove -borderwidth 2 label .prefs.f0.f1.l -text "Web Links:" radiobutton .prefs.f0.f1.r1 -text [tt "Send to Web Browser"] \ -highlightthickness 0 \ -variable webtype -value sendmosaic -relief flat \ -command {msgpopup [tt "Note..."] [tt "this works with Mosaic and Netscape, not other browsers - you need the xm script"]} radiobutton .prefs.f0.f1.r2 -text [tt "Start WWW Client"] \ -highlightthickness 0 \ -variable webtype -value startmosaic -relief flat radiobutton .prefs.f0.f1.r4 -text [tt "Built in"] \ -highlightthickness 0 \ -variable webtype -value builtin -relief flat radiobutton .prefs.f0.f1.r3 -text [tt "Add to cut buffer"] \ -highlightthickness 0 \ -variable webtype -value cutbuffer -relief flat frame .prefs.f0.f1.f label .prefs.f0.f1.f.l -text [tt "WWW Client"] entry .prefs.f0.f1.f.wwwname -width 10 -relief sunken .prefs.f0.f1.f.wwwname insert 0 $webclient frame .prefs.f0.f1.f2 label .prefs.f0.f1.f2.l -text [tt "WWW Proxy"] entry .prefs.f0.f1.f2.wwwproxy -width 15 -relief sunken .prefs.f0.f1.f2.wwwproxy insert 0 $webproxy tixAddBalloon .prefs.f0.f1.f2 Frame [tt "Enter your web proxy in the form \"host:port\"."] pack .prefs.f0.f1.l -side top pack .prefs.f0.f1.r1 -side top -anchor w pack .prefs.f0.f1.r2 -side top -anchor w pack .prefs.f0.f1.r4 -side top -anchor w pack .prefs.f0.f1.r3 -side top -anchor w pack .prefs.f0.f1.f.l -side left pack .prefs.f0.f1.f.wwwname -side right pack .prefs.f0.f1.f -side top -anchor w pack .prefs.f0.f1.f2.l -side left pack .prefs.f0.f1.f2.wwwproxy -side right pack .prefs.f0.f1.f2 -side top -anchor w pack .prefs.f0.f1 -side left -anchor n -fill y -expand true pack .prefs.f0 -side top frame .prefs.f2 -borderwidth 2 -relief groove pack .prefs.f2 -side top button .prefs.f2.b -text "Specify Tools for Media Formats" \ -command select_startup_rule pack .prefs.f2.b -side left frame .prefs.f4 -borderwidth 2 -relief groove pack .prefs.f4 -side top label .prefs.f4.l -text "User Interface Style" pack .prefs.f4.l -side top frame .prefs.f4.f pack .prefs.f4.f -side top -expand true -fill x frame .prefs.f4.f.l -relief groove -borderwidth 2 pack .prefs.f4.f.l -side left -fill y -expand true label .prefs.f4.f.l.l -text "Create Session:" pack .prefs.f4.f.l.l -side top -anchor w global ifstyle radiobutton .prefs.f4.f.l.a -text "Normal Interface" \ -highlightthickness 0 \ -variable ifstyle(create) -value norm pack .prefs.f4.f.l.a -side top -anchor w radiobutton .prefs.f4.f.l.b -text "Technical Interface" \ -highlightthickness 0 \ -variable ifstyle(create) -value tech pack .prefs.f4.f.l.b -side top -anchor w frame .prefs.f4.f.m -relief groove -borderwidth 2 pack .prefs.f4.f.m -side left -fill y -expand true label .prefs.f4.f.m.l -text "View Session:" pack .prefs.f4.f.m.l -side top -anchor w global ifstyle radiobutton .prefs.f4.f.m.a -text "Normal Interface" \ -highlightthickness 0 \ -variable ifstyle(view) -value norm pack .prefs.f4.f.m.a -side top -anchor w radiobutton .prefs.f4.f.m.b -text "Technical Interface" \ -highlightthickness 0 \ -variable ifstyle(view) -value tech pack .prefs.f4.f.m.b -side top -anchor w frame .prefs.f1 button .prefs.f1.ok -text [tt "Apply Prefs"] -command {\ set webclient [.prefs.f0.f1.f.wwwname get];\ set webproxy [.prefs.f0.f1.f2.wwwproxy get];\ reshow_sessions $showwhich;\ catch {destroy .ps};\ destroy .prefs} tixAddBalloon .prefs.f1.ok Button [tt "Apply the changes you've made"] pack .prefs.f1.ok -side left -fill x -expand true button .prefs.f1.save -text [tt "Apply & Save Prefs"] -command {\ set webclient [.prefs.f0.f1.f.wwwname get];\ set webproxy [.prefs.f0.f1.f2.wwwproxy get];\ reshow_sessions $showwhich;\ save_prefs;\ catch {destroy .ps};\ destroy .prefs} tixAddBalloon .prefs.f1.save Button [tt "Apply the changes you've made and also save them for next time"] pack .prefs.f1.save -side left -fill x -expand true pack .prefs.f1 -side top -fill x -expand true move_onscreen .prefs } proc save_prefs {} { global balloonHelp if {[file isdirectory [resource sdrHome]]==0} { catch {file mkdir [resource sdrHome]} msg } if {[file isdirectory [resource sdrHome]]==0} { errorpopup "Error Creating Directory" "I can't save your preferences because I can't create the directory [resource sdrHome] $msg" return } set file [open "[resource sdrHome]/prefs" w] allprefprocs save $file puts $file "set balloonHelp $balloonHelp" puts $file "set_balloon_help $balloonHelp" close $file give_status_msg [tt "Preferences Saved"] } proc help {} { global balloonHelp catch {destroy .help} toplevel .help wm title .help "Sdr: Help" posn_win .help frame .help.f -relief groove -borderwidth 2 pack .help.f -side top message .help.f.l -aspect 150 -text "Sdr is a session directory tool. It is rather like a TV Guide, except it lists sessions to be multicast on the Mbone rather than programmes broadcast on radio and television. What's more, sdr allows you to join the sessions listed, sdr allows you to create and advertise sessions yourself, and sdr affords calling people directly to participate in a session. So essentially, sdr does the following: 1. Allows you to see what sessions are on and to join them. 2. Allows you to advertise sessions yourself. 3. Allows you to make calls to people. Select \"balloon help\" if you'd like to know what sdr's buttons and controls do. Select \"more help\" to view the full sdr help system." pack .help.f.l -side top pack [frame .help.f.f] -side top -fill x -expand true checkbutton .help.f.f.mode -text [tt "Balloon Help"] -variable balloonHelp \ -onvalue 1 -offvalue 0 -command {set_balloon_help $balloonHelp} \ -relief raised pack .help.f.f.mode -side left -fill x -expand true button .help.f.f.about -text [tt "More Help!"] -command "destroy .help;webdisp help:about" -pady 0 -highlightthickness 0 pack .help.f.f.about -side left -fill x -expand true tixAddBalloon .help.f.f.mode Button [tt "Click here to disable balloon help"] tixAddBalloon .help.f.f.about Button [tt "Click here to access sdr's full help system"] label .help.f.bugs -text "Please report bugs and suggestions to sdr@cs.ucl.ac.uk" pack .help.f.bugs -side top -anchor w button .help.f.dismiss -text [tt "Dismiss"] -command "destroy .help" \ -highlightthickness 0 tixAddBalloon .help.f.dismiss Button [tt "Click here to hide this window"] pack .help.f.dismiss -side bottom -fill x move_onscreen .help log "showing help at [getreadabletime]" } proc hide_session {aid} { global ldata showwhich sessbox set list $ldata($aid,list) set box $sessbox($list) set posn [lindex [$box yview] 0] set ldata($aid,vstate) 0 if {[string compare $showwhich "pref"]==0} { save_prefs reshow_sessions $showwhich } $box yview moveto $posn } proc pref_sessions {win} { global ldata prefs fullix fullnumitems # catch {destroy .ps} # toplevel .ps # wm title .ps [tt "Preferred Session List"] # posn_win_rel .ps .prefs frame $win.f1 -relief sunken -borderwidth 1 # set height $fullnumitems set height 15 # if {$height ==0} {set height 1} listbox $win.f1.l1 -width 25 -height $height \ -yscroll "set_prefs_lbscroll $win"\ -relief flat \ -selectforeground [resource activeForeground] \ -selectbackground [resource activeBackground] \ -highlightthickness 0 tixAddBalloon $win.f1.l1 ListBox [tt "Click on a session name to make it visible/hidden in the main session window"] listbox $win.f1.l2 -width 7 -height $height \ -yscroll "set_prefs_lbscroll $win"\ -relief flat \ -selectforeground [resource activeForeground] \ -selectbackground [resource activeBackground] \ -highlightthickness 0 tixAddBalloon $win.f1.l2 ListBox [tt "Click on a session to make it visible/hidden in the main session window"] scrollbar $win.f1.sb \ -command "set_prefs_scroll $win" \ -background [resource scrollbarForeground] \ -troughcolor [resource scrollbarBackground] \ -borderwidth 1 -relief flat \ -highlightthickness 0 #TBD # -foreground [option get . scrollbarForeground Sdr] \ # -activeforeground [option get . scrollbarActiveForeground Sdr] foreach aid $prefs(show_aids) { $win.f1.l1 insert end $ldata($aid,session) if {$prefs(show_aid_$aid)==1} { $win.f1.l2 insert end "visible" } else { $win.f1.l2 insert end "--" } } bind $win.f1.l1 <1> "%W selection set \[%W nearest %y\];update;\ toggle_pref_session $win \[%W nearest %y\]" bind $win.f1.l2 <1> "%W selection set \[%W nearest %y\];update;\ toggle_pref_session $win \[%W nearest %y\]" #packing order determines which disappear first if you shrink #the window pack $win.f1.sb -side right -fill y pack $win.f1.l2 -side right -fill y -expand true pack $win.f1.l1 -side left -fill y -expand true pack $win.f1 -side top -fill both -expand true } proc set_prefs_scroll {win args} { eval $win.f1.l1 yview $args eval $win.f1.l2 yview $args } proc set_prefs_lbscroll {win args} { eval $win.f1.l1 yview moveto [lindex $args 0] eval $win.f1.l2 yview moveto [lindex $args 0] eval $win.f1.sb set $args } proc toggle_pref_session {win i} { global prefs if {[string compare $i ""]==0} {return 0} set aid [lindex $prefs(show_aids) $i] set prefs(show_aid_$aid) [expr 1-$prefs(show_aid_$aid)] if {$prefs(show_aid_$aid)==1} { $win.f1.l2 insert $i [tt "visible"] } else { $win.f1.l2 insert $i "--" } $win.f1.l2 delete [expr $i+1] } proc pref_sess_enable {win} { global prefs if {$prefs(show_showwhich)=="pref"} { $win.f1.l1 configure -foreground [option get . foreground Sdr] $win.f1.l2 configure -foreground [option get . foreground Sdr] } else { $win.f1.l1 configure -foreground [option get . disabledForeground Sdr] $win.f1.l2 configure -foreground [option get . disabledForeground Sdr] } } set durationix 2 set monthix 0 set dayix 0 set hrix 0 set ttl 16 proc unix_to_ntp {unixtime} { set oddoffset 2208988800 if {$unixtime==0} {return 0} return [format %u [expr $unixtime + $oddoffset]] } proc ntp_to_unix {ntptime} { set oddoffset 2208988800 if {($ntptime==0)||($ntptime==1)} {return $ntptime} return [format %u [expr $ntptime - $oddoffset]] } set zone(no_of_zones) 0 set zone(cur_zone) 0 proc add_ttl_scope {sap_addr sap_port base_addr netmask} { # #note this must be done after all admin scope zones have been added. #this must not be called more than once! # global zone set no_of_zones $zone(no_of_zones) set zone(sap_addr,$no_of_zones) $sap_addr set zone(sap_port,$no_of_zones) $sap_port set zone(base_addr,$no_of_zones) $base_addr set zone(netmask,$no_of_zones) $netmask sd_listen $sap_addr $sap_port set zone(ttl_scope) $no_of_zones } proc add_admin {name sap_addr sap_port base_addr netmask ttl} { # #add a new admin scope zone, modify an existing one or remove #an old one. #to remove one, specify its name and set sap_addr to "" # global zone set no_of_zones $zone(no_of_zones) for {set i 0} {$i < $no_of_zones} {incr i} { if {$zone(name,$i)==$name} { if {$sap_addr==""} { for {set j $i} {$j<[expr $no_of_zones-1]} {incr j} { set zone(name,$j) $zone(name,[expr $j+1]) set zone(sap_addr,$j) $zone(sap_addr,[expr $j+1]) set zone(sap_port,$j) $zone(sap_port,[expr $j+1]) set zone(base_addr,$j) $zone(base_addr,[expr $j+1]) set zone(netmask,$j) $zone(netmask,[expr $j+1]) set zone(ttl,$j) $zone(ttl,[expr $j+1]) } incr zone(no_of_zones) -1 return 0 } else { set no_of_zones $i incr zone(no_of_zones) -1 } } } set zone(name,$no_of_zones) $name set zone(sap_addr,$no_of_zones) $sap_addr set zone(sap_port,$no_of_zones) $sap_port sd_listen $sap_addr $sap_port set zone(base_addr,$no_of_zones) $base_addr set zone(netmask,$no_of_zones) $netmask set zone(ttl,$no_of_zones) $ttl incr zone(no_of_zones) } proc sdr_new_session_hook {advert} { } proc sdr_delete_session_hook {advert} { } set fh [font metrics -adobe-courier-bold-r-normal--*-120-*-*-m-*-iso8859-1 -linespace] set fw [font measure -adobe-courier-bold-r-normal--*-120-*-*-m-*-iso8859-1 m] set font -adobe-courier-bold-r-normal--*-120-*-*-m-*-iso8859-1 set tmp 0 catch {set tmp [label .test -font $font];destroy .test} if {$tmp==0} { set font 8x13 set fh 13 set fw 8 } for {set i 1} {$i <= 31} {incr i} { set ending($i) "th" } foreach i {1 21 31} { set ending($i) "st" } foreach i {2 22} { set ending($i) "nd" } foreach i {3 23} { set ending($i) "rd" } proc calendar {} { global ldata fullix fullnumitems daysinmonth taglist fh fw font ifstyle catch {destroy .cal} catch {unset taglist} toplevel .cal wm title .cal "Sdr: Daily Listings" posn_win .cal frame .cal.f0 -borderwidth 2 -relief groove if {$ifstyle(labels)=="long"} { label .cal.f0.l -text "Click on a day to show what's on." \ -anchor w -font [option get . infoFont Sdr] pack .cal.f0.l -side top -fill x -expand true } canvas .cal.f0.c -height [expr 8 * $fh] -width [expr 96 * $fw] \ -relief flat -highlightthickness 0 tixAddBalloon .cal.f0.c Frame [tt "Highlighted dates are days that \ have sessions scheduled. Click on a date to get the listing for that \ day."] set fg [option get . foreground Sdr] set tstr [gettimenow] set daynow [fixint [lindex $tstr 2]] set monnow [fixint [lindex $tstr 1]] set yearnow [fixint [lindex $tstr 0]] for {set i 0} {$i < 3} {incr i} { set mon [expr $monnow + $i] set year $yearnow if {$mon>12} { incr mon -12 incr year } .cal.f0.c addtag mon$i withtag \ [.cal.f0.c create text [expr $i*$fw*32] 0 -anchor nw\ -fill $fg -font $font] if {$i==0} { set utime [gettimeofday] set day [fixint [clock format $utime -format {%d}]] set begin [expr $utime - (($day-1)*86400)] set first($mon) [clock format $begin -format {%w}] set mname [clock format $begin -format {%B}] } else { set utime [expr $begin+($i*2678400)] set day [fixint [clock format $utime -format {%d}]] set next [expr $utime - (($day-1)*86400)] set first($mon) [clock format $next -format {%w}] set mname [clock format $next -format {%B}] } for {set d 1} {$d <= [lindex $daysinmonth [expr $mon - 1]]} {incr d} { highlight_day $d $mon $year $first($mon) $monnow grey $fg "" 0 -1 -1 } #do the month and day names .cal.f0.c insert mon$i 0 "$mname\n" for {set d 0} {$d < 7} {incr d} { set str [getdayname $d] .cal.f0.c insert mon$i end "[getdayname $d] " if {[string length $str]==2} {.cal.f0.c insert mon$i end " "} } } pack .cal.f0 -side top pack .cal.f0.c -side top frame .cal.f2 -borderwidth 2 -relief groove button .cal.f2.dismiss -text [tt "Dismiss"] \ -command {catch {unset taglist};destroy .cal} \ -highlightthickness 0 pack .cal.f2.dismiss -side left -expand true -fill x pack .cal.f2 -side top -expand true -fill x # highlight_day $daynow 0 $year $first([expr $monnow+0]) $monnow white blue today for {set i 0} {$i < $fullnumitems} {incr i} { set aid $fullix($i) for {set t 0} {$t < $ldata($aid,no_of_times)} {incr t} { set starttime $ldata($aid,starttime,$t) set endtime $ldata($aid,endtime,$t) #don't show continuous sessions if {$starttime==0} { continue } if {$ldata($aid,time$t,no_of_rpts)==0} { #don't show sessions continuously active for more than 2 weeks if {[expr $endtime-$starttime]>1209600} { continue } if {$starttime < [gettimeofday]} {set starttime [gettimeofday]} if {$endtime > ([gettimeofday]+8035200)} { set endtime [expr [gettimeofday]+8035200] } set startstr [gettime $starttime] set sday [fixint [lindex $startstr 2]] set smon [fixint [lindex $startstr 1]] set endstr [gettime $endtime] set eday [fixint [lindex $endstr 2]] set emon [fixint [lindex $endstr 1]] set syear [fixint [lindex $startstr 0]] set remon $emon if {$emon<$smon} { set remon [expr $emon+12] } for {set tmon $smon} {$tmon <= $remon} {incr tmon} { if {$tmon>12} { set mon [expr $tmon-12] incr syear } else { set mon $tmon } if {$mon==$smon} { set som $sday } else { set som 1 } if {$mon==$emon} { set eom $eday } else { set eom [lindex $daysinmonth [expr $mon - 1]] } for {set day $som} {$day <= $eom} {incr day} { catch { highlight_day $day $mon $syear $first([expr $mon+0]) $monnow [option get . activeBackground Sdr] [option get . hotForeground Sdr] \"$aid\" $t -1 -1} } } } else { set realendtime $endtime for {set r 0} {$r<$ldata($aid,time$t,no_of_rpts)} {incr r} { for {set o 0} {$o<[llength $ldata($aid,time$t,offset$r)]} {incr o} { set rctr 0 set starttime [expr $ldata($aid,starttime,$t) + [lindex $ldata($aid,time$t,offset$r) $o]] while {$starttime < $realendtime} { set endtime [expr $starttime + $ldata($aid,time$t,duration$r)] #8035200 is 3 months in seconds... if {$starttime > ([gettimeofday]+8035200)} { break; } if {$endtime > ([gettimeofday]+8035200)} { set endtime [expr [gettimeofday]+8035200] } if {$endtime < [gettimeofday]} { set starttime [expr $starttime + $ldata($aid,time$t,interval$r)] incr rctr continue } if {$starttime < [gettimeofday]} { set startstr [gettime [gettimeofday]] } else { set startstr [gettime $starttime] } set sday [fixint [lindex $startstr 2]] set smon [fixint [lindex $startstr 1]] set endstr [gettime $endtime] set syear [fixint [lindex $startstr 0]] set etime [expr [fixint [lindex $endstr 3]]*60 + \ [fixint [lindex $endstr 4]]] #anything running < 30 mins into the next day isn't #worth showing... if {$etime<30} { set endtime [expr $endtime-1800] set endstr [gettime $endtime] } set eday [fixint [lindex $endstr 2]] set emon [fixint [lindex $endstr 1]] set remon $emon if {$emon<$smon} { set remon [expr $emon+12] } for {set tmon $smon} {$tmon <= $remon} {incr tmon} { if {$tmon>12} { set mon [expr $tmon-12] incr syear } else { set mon $tmon } if {$mon==$smon} { set som $sday } else { set som 1 } if {$mon==$emon} { set eom $eday } else { set eom [lindex $daysinmonth [expr $mon - 1]] } for {set day $som} {$day <= $eom} {incr day} { catch { highlight_day $day $mon $syear $first([expr $mon+0]) $monnow [option get . activeBackground Sdr] [option get . hotForeground Sdr] \"$aid\" $t $r $rctr $o} } } set starttime [expr $starttime + $ldata($aid,time$t,interval$r)] incr rctr } } } } } } move_onscreen .cal log "calendar displayed at [getreadabletime]" } proc highlight_day {day mon yr offset monnow col fgcol aid tindex rindex rctr {off 0}} { global taglist fh fw font set tday [expr $day+$offset] set tmon [expr $mon-$monnow] if {$tmon<0} { incr tmon 12 } set code 0 set dow [getdayname [expr ($day+$offset-1)%7] -long] catch {set code $taglist($day.$mon)} if {$code==0} { set xpos [expr ((($tday-1)%7) + ($tmon*8))*$fw*4 ] set ypos [expr ((($tday-1) / 7)+2)*$fh] if {$day < 10} { set daystr " $day" } else { set daystr $day } if {[string compare $aid ""]!=0} { .cal.f0.c addtag $day.$mon withtag \ [.cal.f0.c create rectangle [expr $xpos - 2] $ypos \ [expr $xpos + ($fw*2) +2] [expr $ypos + $fh - 1] -fill $col \ -outline [option get . foreground Sdr]] .cal.f0.c addtag t.$day.$mon withtag \ [.cal.f0.c create text $xpos $ypos -anchor nw \ -fill [option get . hotForeground Sdr] -font $font \ -text "$daystr"] set taglist($day.$mon) "$aid $tindex $rindex $rctr $off" .cal.f0.c bind t.$day.$mon <1> \ "display_bookings $dow $day $mon $yr \$taglist($day.$mon)" .cal.f0.c bind t.$day.$mon \ ".cal.f0.c itemconfigure t.$day.$mon -fill \ [option get . activehotForeground Sdr]" .cal.f0.c bind t.$day.$mon \ ".cal.f0.c itemconfigure t.$day.$mon -fill $fgcol" } else { .cal.f0.c create text $xpos $ypos -anchor nw -fill $fgcol \ -text "$daystr" -font $font } } else { set taglist($day.$mon) "$taglist($day.$mon)\n$aid $tindex $rindex $rctr $off" } } proc display_bookings {dow day mon yr bookings} { global ldata ifstyle ending set title \ "[tt "Sessions on"] $dow $day$ending($day) [getmonname $mon -long]" set blist [split $bookings "\n"] set fg [option get . foreground Sdr] set hotfg [option get . hotForeground Sdr] set ahotfg [option get . activehotForeground Sdr] set booknum 0 set aid "" foreach booking $blist { if {[string compare [lindex $booking 0] $aid] != 0} { incr booknum 1 } set aid [lindex $booking 0] } set win .cal.day$day,$mon if {[winfo exists $win]} { return 0 } frame $win -borderwidth 2 -relief groove pack $win -before .cal.f2 -side top -fill x -expand true frame $win.f -borderwidth 2 -relief groove pack $win.f -side top -fill both -expand true frame $win.f.f -borderwidth 0 pack $win.f.f -side top -fill x -expand true label $win.f.f.l -text $title pack $win.f.f.l -side left label $win.f.f.exp -font [option get . infoFont Sdr] -text "" \ -justify l -anchor w pack $win.f.f.exp -side left -fill x -expand true if {$ifstyle(labels)=="long"} { $win.f.f.exp configure -text [tt "Click on a session to see details of it"] } canvas $win.f.c -height [expr ($booknum*15)+30] -width 650 -relief sunken \ -highlightthickness 0 for {set t 0} {$t < 24} {incr t} { $win.f.c addtag hour$t withtag \ [$win.f.c create text [expr ($t * 20)+10] 5 -anchor n\ -fill $fg -font [option get . font Sdr]] $win.f.c create line [expr ($t * 20) +20 ] 20\ [expr ($t * 20) +20 ] 30 -fill $fg $win.f.c create line [expr ($t * 20) +10 ] 20\ [expr ($t * 20) +10 ] [expr ($booknum*15)+20]\ -fill $fg if {$t<10} { set time "0$t" } else { set time $t } $win.f.c insert hour$t 0 "$time" } $win.f.c create line 490 20 490 [expr ($booknum*15)+20] -fill $fg $win.f.c create line 10 20 490 20 -fill $fg $win.f.c create line 10 [expr ($booknum*15)+20] 490 [expr ($booknum*15)+20] -fill $fg set lnum -15 set prevaid "" foreach booking $blist { if {[string compare $booking "today"]!=0} { set aid [string trim [lindex $booking 0] "\""] #check the session information does still exist set tmp 0 catch {set tmp $ldata($aid,session)} if {$tmp==0} { break } set t [lindex $booking 1] set r [lindex $booking 2] set rctr [lindex $booking 3] set offset [lindex $booking 4] if {[string compare $aid $prevaid]!=0} { incr lnum 15 } set starttime $ldata($aid,starttime,$t) if {$r!=-1} { set starttime [expr $starttime + [lindex $ldata($aid,time$t,offset$r) $offset] \ + ($rctr*$ldata($aid,time$t,interval$r))] set endtime [expr $starttime +$ldata($aid,time$t,duration$r)] } else { set endtime $ldata($aid,endtime,$t) } set startstr [gettime $starttime] set sday [fixint [lindex $startstr 2]] set smon [fixint [lindex $startstr 1]] set syr [fixint [lindex $startstr 0]] set endstr [gettime $endtime] set etime [expr [fixint [lindex $endstr 3]]*60 + \ [fixint [lindex $endstr 4]]] #anything running < 30 mins into the next day isn't #worth showing as ending the next day if {$etime<30} { set endtime [expr $endtime-(60*($etime+1))] set endstr [gettime $endtime] } set eday [fixint [lindex $endstr 2]] set emon [fixint [lindex $endstr 1]] set eyr [fixint [lindex $endstr 0]] if {($day==$sday)&&($mon==$smon)&&($yr==$syr)} { set shr [string trimleft [lindex $startstr 3] "0"] set smin [expr [lindex $startstr 4]/3] set larrow 1 } else { set shr 0 set smin 0 set larrow 0 } if {($day==$eday)&&($mon==$emon)&&($yr==$eyr)} { set ehr [string trimleft [lindex $endstr 3] "0"] set emin [expr [lindex $endstr 4]/3] set rarrow 1 } else { set ehr 24 set emin 0 set rarrow 0 } #need to be able to cope with multiple active times per entry set tag "$sday:$shr:$smin:$lnum" if {$shr==""} {set shr 0} if {$ehr==""} {set ehr 0} $win.f.c addtag l$tag withtag [\ $win.f.c create line \ [expr ($shr * 20)+10+($smin)]\ [expr 25+$lnum] \ [expr ($ehr * 20)+10+($emin)] \ [expr 25+$lnum] \ -fill $hotfg -width 4 ] if {$larrow==1} { if {$rarrow==1} { $win.f.c itemconfigure l$tag -arrow both } else { $win.f.c itemconfigure l$tag -arrow first } } else { if {$rarrow==1} { $win.f.c itemconfigure l$tag -arrow last } } $win.f.c bind l$tag <1> "popup $aid \$ifstyle(view) advert" $win.f.c bind l$tag \ "$win.f.c itemconfigure t$lnum -fill $ahotfg;\ $win.f.c itemconfigure l$tag -fill $ahotfg" $win.f.c bind l$tag \ "$win.f.c itemconfigure t$lnum -fill $hotfg;\ $win.f.c itemconfigure l$tag -fill $hotfg" $win.f.c create line \ [expr ($ehr * 20)+10+($emin)] \ [expr 25+$lnum] \ 495 [expr 25+$lnum] \ -fill $hotfg if {[string compare $aid $prevaid]!=0} { $win.f.c addtag t$lnum withtag \ [$win.f.c create text 495 \ [expr 25+$lnum] -anchor w\ -fill $hotfg -font [option get . font Sdr]] $win.f.c insert t$lnum 0 $ldata($aid,session) $win.f.c bind t$lnum <1> "popup $aid \$ifstyle(view) advert" $win.f.c bind t$lnum \ "$win.f.c itemconfigure t$lnum -fill $ahotfg;\ $win.f.c itemconfigure l$tag -fill $ahotfg" $win.f.c bind t$lnum \ "$win.f.c itemconfigure t$lnum -fill $hotfg;\ $win.f.c itemconfigure l$tag -fill $hotfg" } set prevaid $aid } } button $win.f.f.dismiss -text "[tt Hide] $day [getmonname $mon -long]" \ -command "destroy $win" -font [option get . infoFont Sdr] \ -borderwidth 1 -relief raised -pady 0 -padx 1 \ -highlightthickness 0 pack $win.f.f.dismiss -side right pack $win.f.c -side bottom -fill both -expand true # wm minsize $win 650 50 # move_onscreen $win } proc sdr2.2_fix_cache {} { set shortname [glob -nocomplain ~] if { $shortname != "" } { set dirname "$shortname/.sdr" } else { set dirname "/.sdr" } # set dirname "[glob -nocomplain ~]/.sdr" if {$dirname=="//.sdr"} { set dirname "/.sdr" } if {[file isdirectory $dirname]!=0} { #we have a .sdr dir if {[file isdirectory $dirname/cache]==0} { #but no cache subdir #this means the last version was pre-sdr2.2a5 catch {file mkdir $dirname/cache} if {[file isdirectory $dirname/cache]==0} { catch {puts "couldn't create cache directory `$dirname/cache'"} return 0 } set filelist [glob -nocomplain $dirname/*] foreach file $filelist { set fname [file tail $file] if {($fname!="plugins")&&($fname!="cache")} { exec mv $dirname/$fname $dirname/cache } } } } } proc dotted_decimal_to_decimal {dd} { set blist [split $dd "."] set res 0 for {set i 0} {$i < 4} {incr i} { set res [expr (($res * 256)+[lindex $blist $i]) ] } return [format %u $res] } proc make_session {aid {mediavar {}}} { global ldata set msg "v=0" set msg "$msg\no=$ldata($aid,creator) $ldata($aid,createtime) $ldata($aid,modtime) IN IP4 $ldata($aid,createaddr)" set msg "$msg\ns=$ldata($aid,session)" set desc $ldata($aid,desc) regsub -all "\n" $desc " " desc set msg "$msg\ni=$desc" if {$ldata($aid,uri)!=0} { set msg "$msg\nu=$ldata($aid,uri)" } foreach i $ldata($aid,emaillist) { set msg "$msg\ne=$i" } foreach i $ldata($aid,phonelist) { set msg "$msg\np=$i" } #AUTH commented next one # if {$ldata($aid,multicast)!=""} { #set msg "$msg\nc=IN IP4 $ldata($aid,multicast)/$ldata($aid,ttl)" #} for {set i 0} {$i < $ldata($aid,no_of_times)} {incr i} { if {$ldata($aid,starttime,$i)==0} {set start 0} \ else { set start [format %u [unix_to_ntp $ldata($aid,starttime,$i)]] } if {$ldata($aid,endtime,$i)==0} {set stop 0} \ else {set stop [format %u [unix_to_ntp $ldata($aid,endtime,$i)]]} set msg "$msg\nt=$start $stop" for {set r 0} {$r < $ldata($aid,time$i,no_of_rpts)} {incr r} { set offsets {} foreach offset $ldata($aid,time$i,offset$r) { lappend offsets [make_rpt_time $offset] } set msg "$msg\n[format "r=%s %s %s"\ [make_rpt_time $ldata($aid,time$i,interval$r)]\ [make_rpt_time $ldata($aid,time$i,duration$r)]\ $offsets]" } } foreach i [split $ldata($aid,vars) "\n"] { set msg "$msg\na=$i" } if {[string compare $mediavar ""] != 0} { global $mediavar } for {set i 0} {$i < $ldata($aid,medianum)} {incr i} { set media $ldata($aid,$i,media) if {[string compare $mediavar ""] != 0 && [set [set mediavar]($media)] == 0} { continue } set port $ldata($aid,$i,port) set proto $ldata($aid,$i,proto) set fmt $ldata($aid,$i,fmt) set msg "$msg\nm=$media $port $proto $fmt" set addr $ldata($aid,$i,addr) set newttl $ldata($aid,$i,ttl) set msg "$msg\nc=IN IP4 $addr/$newttl" if {[info exists ldata($aid,$i,mediakey)]} { set key $ldata($aid,$i,mediakey) } else { set key "" } if { [ string compare $key ""] !=0 } { set msg "$msg\nk=clear:$key" } if {$ldata($aid,$i,layers)>1} { set msg "$msg/$ldata($aid,$i,layers)" } set varlist [split $ldata($aid,$i,vars) "\n"] foreach var $varlist { set msg "$msg\na=$var" } } return $msg } proc valid_mcast_address {addr} { if {$addr==""} {return 1} set parts [split $addr "."] if {[llength $parts]!=4} { # putlogfile "Invalid address format" return 0 } set b1 [lindex $parts 0] if {($b1<224)|($b1>239)} { # putlogfile "Invalid most significant byte" return 0 } for {set b 1} {$b <= 3} {incr b} { set byte [lindex $parts $b] if {($byte<0)|($byte>255)} { return 0 } } return 1 } set durations "30 minutes\n1 hour\n2 hours\n3 hours\n4 hours\n5 hours\n6 hours\n7 hours\n8 hours\n9 hours\n10 hours\n11 hours\n12 hours\n1 day\n2 days\n3 days\n4 days\n5 days\n6 days\n1 week\n8 days\n9 days\n10 days\n11 days\n12 days\n13 days\n2 weeks\n3 weeks\n4 weeks" set realdurations "30\n60\n120\n180\n240\n300\n360\n420\n480\n540\n600\n\ 660\n720\n\ 1440\n2880\n4320\n5760\n7200\n8640\n10080\n11520\n12960\n14400\n\ 15840\n17280\n18720\n20160\n30240\n40320" set months "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec" set daysinmonth "31 28 31 30 31 30 31 31 30 31 30 31" set langstrs(fr,minutes) minutes set langstrs(fr,hour) heur set langstrs(fr,hours) heures set langstrs(fr,day) jour set langstrs(fr,days) jours set langstrs(fr,week) semaine set langstrs(fr,weeks) semaines set langstrs(de,minutes) minuten set langstrs(de,hour) uhr set langstrs(de,hours) uhr set langstrs(de,day) tag set langstrs(de,days) tag set langstrs(de,week) woche set langstrs(de,weeks) wochen set availlangs {fr de} proc map_duration {str lang} { global availlangs langstrs set p1 [lindex [split $str " "] 0] set p2 [lindex [split $str " "] 1] if {[lsearch $availlangs $lang]!=-1} { set p2 $langstrs($lang,$p2) } return "$p1 $p2" } proc get_duration {ix} { global durations lang set l [split $durations "\n"] return [map_duration [lindex $l $ix] $lang] } proc get_realduration {ix} { global realdurations set l [split $realdurations "\n"] return [lindex $l $ix] } proc get_duration_ix_by_time {secs} { global realdurations set l [split $realdurations "\n"] set mindiff 20160 set mins [expr $secs / 60] for {set i 0} {$i < [llength $l]} {incr i} { if {$mins<= [lindex $l $i]} { return $i } } return 1 } proc is_known_media {media} { global medialist return [lsearch $medialist $media] } proc get_icon {media} { global mediadata medialist if {[lsearch $medialist $media]==-1} { return unknown } else { return $mediadata(icon:$media) } } set typedata(icon:test) test set typedata(icon:meeting) meeting set typedata(icon:broadcast) broadcast set typedata(icon:stest) stest set typedata(icon:smeeting) smeeting set typedata(icon:sbroadcast) sbroadcast #AUTH #set typedata(icon:secure) secure #name mapping allows for internationalisation set typedata(name:test) [tt Test] set typedata(name:meeting) [tt Meeting] set typedata(name:broadcast) [tt Broadcast] set typelist {test meeting broadcast} #AUTH #set typedata(name:secure) [tt Secure] #set typelist {test meeting broadcast secure} #AUTH proc get_type_icon {type authtype enctype} { global typedata typelist if {[lsearch $typelist $type]==-1} { return unknown } else { if { [string compare $authtype "none"] !=0 || [string compare $enctype "none"] !=0} { set type "s$type" } return $typedata(icon:$type) } } proc get_type_name {type} { global typedata typelist if {[lsearch $typelist $type]==-1} { return Unknown } else { return $typedata(name:$type) } } proc periodic_save {interval} { after $interval "write_cache;periodic_save $interval" } # default user_hook is a noop - users should redefine it in # [sdrHome]/sdr.tcl to modify the tool's behavior. proc user_hook {} { } #AUTH proc authinfo {win bgcolour fgcolour authm} { global ldata global $win.visible pack forget $win.buttons.authmsg incr $win.visible -1 if {[set $win.visible]==0} {pack forget $win.buttons} frame $win.authinfo -borderwidth 2 -relief groove set mf [option get . mediumFont Sdr] pack $win.authinfo -side top -fill x -after $win.hidden2 message $win.authinfo.authmsg -aspect 600 -text "Authentication Information: $authm " -font $mf -bg $bgcolour -fg $fgcolour pack $win.authinfo.authmsg -side top -expand true } proc encinfo {win fgcolour bgcolour encm} { global ldata global $win.visible pack forget $win.buttons.encmsg incr $win.visible -1 if {[set $win.visible]==0} {pack forget $win.buttons} frame $win.encinfo -borderwidth 2 -relief groove set mf [option get . mediumFont Sdr] pack $win.encinfo -side top -fill x -after $win.hidden2 message $win.encinfo.encmsg -aspect 800 -text "Encryption Information: $encm " -font $mf -bg $bgcolour -fg $fgcolour pack $win.encinfo.encmsg -side top -expand true } #set where to read config files from if {$tcl_platform(platform) == "windows"} { option add *sdrHome ~/sdr } else { set_resource Sdr.sdrHome [glob ~]/.sdr } initialise_resources parse_plugins "/usr/local/etc/sdr/plugins" yes parse_plugins "[resource sdrHome]/plugins" yes #fix up pre-sdr2.2a5 cache files into the proper location sdr2.2_fix_cache # Set up the order of items in the preferences window set prefprocs "show ifstyle tools web pers people security" #Check for old ~/.sdr.tcl if {([file isfile [glob -nocomplain ~]/.sdr.tcl]) && !([file isfile [resource sdrHome]/sdr.tcl])} { set movedmsg "Note: moved .sdr.tcl" exec mv [glob -nocomplain ~]/.sdr.tcl [glob -nocomplain [resource sdrHome]]/sdr.tcl } add_admin "Local Scope" 239.255.255.255 9875 239.255.0.0 16 15 add_admin "Region (ttl 63)" 224.2.127.254 9875 224.2.128.0 17 63 add_admin "World (ttl 127)" 224.2.127.254 9875 224.2.128.0 17 127 add_ttl_scope 224.2.127.254 9875 224.2.128.0 17 set flag 1 catch {source "/usr/local/etc/sdr/sdr.tcl";set flag 0} if {($flag)&&([file isfile /usr/local/etc/sdr/sdr.tcl])} { set tmp $errorInfo errorpopup [tt "Error executing /usr/local/etc/sdr/sdr.tcl"] $tmp } set flag 1 catch {source "[resource sdrHome]/sdr.tcl";set flag 0} if {($flag)&&([file isfile [resource sdrHome]/sdr.tcl])} { set tmp $errorInfo errorpopup [tt "Error executing [resource sdrHome]/sdr.tcl"] $tmp } # # Set all preferences to their defaults # allprefprocs defaults allprefprocs copyout set save_interval 3600000 #Check for old ~/.sdr_prefs if {([file isfile [glob -nocomplain ~]/.sdr_prefs]) && !([file isfile [resource sdrHome]/prefs])} { if ![info exists movedmsg] { set movedmsg "Note: moved .sdr_prefs" } else { set movedmsg "$movedmsg and .sdr_prefs" } exec mv [glob -nocomplain ~]/.sdr_prefs [glob -nocomplain [resource sdrHome]]/prefs } if [info exists movedmsg] { timedmsgpopup {Moved Files} "$movedmsg to the new location in [resource sdrHome]." 15000 } set flag 1 catch {source "[resource sdrHome]/prefs";set flag 0} if {($flag)&&([file isfile [resource sdrHome]/prefs])} { errorpopup "Error executing [resource sdrHome]/prefs" $errorInfo } foreach media $medialist { set send($media) 0 } set send([lindex $medialist 0]) 1 #create the interface build_interface first #save the session listing every so often periodic_save $save_interval #set the SIP alias for incoming calls set_sipalias $youralias #Run the user's hook. user_hook #DO NOT MODIFY THIS MODULE #This module is automatically derived from cache_crypt.tcl proc load_from_cache {} { set dirname "[resource sdrHome]/cache" if {[file isdirectory $dirname]} { foreach file [glob -nocomplain $dirname/*] { if {[file isfile $file] && [file readable $file]} { load_cache_entry $file clear } } } set dirname "[resource sdrHome]/asymmetric" if {[file isdirectory $dirname]} { foreach file [glob -nocomplain $dirname/*] { if {[file isfile $file] && [file readable $file]} { load_cache_entry $file symm } } } } proc load_from_cache_crypt {} { set dirname "[resource sdrHome]/encrypt" if {[file isdirectory $dirname]} { foreach file [glob -nocomplain $dirname/*] { if {[file isfile $file] && [file readable $file]} { load_cache_entry $file crypt } } } } proc write_cache {} { global ldata fullix # XXX Just a note here: # XXX The user interface is probably destroyed by now, if the user clicked # on quit, so these msgpopups don't do much good. set dirname [resource sdrHome] if {[file isdirectory $dirname]==0} { catch {file mkdir $dirname} if {[file isdirectory $dirname]==0} { msgpopup "Error" "Could not create sdr config directory $dirname" return -1 } } if {[file isdirectory $dirname/cache]==0} { catch {file mkdir $dirname/cache} if {[file isdirectory $dirname/cache]==0} { msgpopup "Error" "Could not create sdr cache directory $dirname/cache" return -1 } } else { set filelist [glob -nocomplain $dirname/cache/*] foreach file $filelist { set tmpaid [file tail $file] set flag 0 catch { set flag $ldata($tmpaid,session) } if {$flag==0} { file delete $file } } } if {[file isdirectory $dirname/encrypt]==0} { catch {file mkdir $dirname/encrypt} if {[file isdirectory $dirname/encrypt]==0} { msgpopup "Error" "Could not create sdr cache directory $dirname/encrypt" return -1 } } else { set filelist [glob -nocomplain $dirname/encrypt/*] foreach file $filelist { set tmpaid [file tail $file] set flag 0 catch { set flag $ldata($tmpaid,session) } if {$flag==0} { file delete $file } } } if {[file isdirectory $dirname/asymmetric]==0} { catch {file mkdir $dirname/asymmetric} if {[file isdirectory $dirname/asymmetric]==0} { msgpopup "Error" "Could not create sdr cache directory $dirname/asymmetric" return -1 } } else { set filelist [glob -nocomplain $dirname/asymmetric/*] foreach file $filelist { set tmpaid [file tail $file] set flag 0 catch { set flag $ldata($tmpaid,session) } if {$flag==0} { file delete $file } } } set ixnames {} catch {set ixnames [array names fullix]} foreach i $ixnames { if {$ldata($fullix($i),trust) != "sip"} { if {$ldata($fullix($i),list) == "norm"} { set filename "$dirname/cache/$fullix($i)" write_cache_entry $fullix($i) $filename clear } else { if {$ldata($fullix($i),key) != ""} { set filename "$dirname/encrypt/$fullix($i)" write_cache_entry $fullix($i) $filename crypt } else { if {($ldata($fullix($i),enctype) == "pgp") || ($ldata($fullix($i),enctype) == "x509" ) } { set filename "$dirname/asymmetric/$fullix($i)" write_cache_entry $fullix($i) $filename symm } else { # its a SIP Invitation } } } } else { # its a SIP Invitation } } } proc write_cache_entry {aid filename security} { global ldata rtp_payload #if there's no sap_addr specified, this was not an announced session #so don't cache it - probably it was a SIP session. set sap_addr "" catch {set sap_addr $ldata($aid,sap_addr)} if {$sap_addr==""} return set source [dotted_decimal_to_decimal $ldata($aid,source)] set heardfrom [dotted_decimal_to_decimal $ldata($aid,heardfrom)] set lastheard $ldata($aid,lastheard) set sap_port $ldata($aid,sap_port) set trust $ldata($aid,trust) set key $ldata($aid,key) set key $ldata($aid,key) set auth $ldata($aid,authtype) set enc $ldata($aid,enctype) if {$ldata($aid,asym_keyid) !=""} { set k1 $ldata($aid,asym_keyid) } else { set k1 "1" } if {$ldata($aid,enc_asym_keyid) !=""} { set k2 $ldata($aid,enc_asym_keyid) } else { set k2 "2" } set adstr "n=$source $heardfrom $lastheard $sap_addr $sap_port $ldata($aid,ttl) $trust $auth $enc $ldata($aid,authstatus) $ldata($aid,encstatus) $k1 $k2 \nk=$key\n[make_session $aid]" switch $security { clear { if {$auth!="none"} { append adstr "\nz=\n" write_authentication $filename $adstr [string length $adstr] $aid } else { set file [open $filename w+] puts $file $adstr close $file } } symm { append adstr "\nz=\n" write_encryption $filename $adstr [string length $adstr] $aid $auth $enc } crypt { if {$auth!="none" } { append adstr "\nz=\n" } write_crypted_file $filename $adstr [string length $adstr] $aid $auth } } } # set adstr "n=$source $heardfrom $lastheard $sap_addr $sap_port $ldata($aid,ttl) $trust\nk=$key\n[make_session $aid]" #if {$security=="clear"} { #set file [open $filename w+] #puts $file $adstr #close $file #} else { #write_crypted_file $filename $adstr [string length $adstr] #} ##} #command line interface to Sdr. mjh@isi.edu, 1998 # #This is an attempt at a command line interface for sdr. It is not #intended to replace the GUI, but rather to aid sdr's use by blind #people for whom a GUI is of no use, but a command line interface #can be used with a text-to-speech system. Thanks to Jeremy Hall #for the suggestion. proc cli_say_sessions {which} { global cli_ixmap fullnumitems fullix showwhich ldata set timespec {all current future} foreach el [array names cli_ixmap] { unset cli_ixmap($el) } puts "Listing of $which sessions:" set ix 0 for {set i 0} {$i < $fullnumitems} {incr i} { set aid $fullix($i) if {[string first $which $timespec]>=0} { set show [listing_criteria $aid $which] } else { if {$ldata($aid,type)==$which} { set show 1 } else { set show 0 } } if {$show} { incr ix set cli_ixmap($ix) $aid puts "$ix: $ldata($aid,session)" } } } proc cli_map_ix_to_aid {ix} { global cli_ixmap if {[info exists cli_ixmap($ix)]} { set aid $cli_ixmap($ix) } else { puts "Invalid session number. Valid session numbers are 1 to [llength [array names cli_ixmap]]." } } proc cli_describe_session {ix} { global ldata set aid [cli_map_ix_to_aid $ix] set desc [cli_describe_session_by_aid $aid] } proc cli_describe_session_by_aid {aid} { global ldata if {$aid==0} return set desc "" set desc "$desc\n$ldata($aid,session)." set desc "$desc\nDescription: [string trimright $ldata($aid,desc) "."]." set desc "$desc\nCreated by $ldata($aid,creator) at $ldata($aid,createaddr)." if {$ldata($aid,tfrom)!=0} { regsub "\n" "[text_times_english $aid]." " " time set desc "$desc\n$time" } else { set desc "$desc\nThis session is not time-bounded." } for {set i 0} {$i < $ldata($aid,medianum)} {incr i} { set media $ldata($aid,$i,media) if {$i == 0} { set medialist $media } elseif {$i < [expr $ldata($aid,medianum)-1]} { set medialist "$medialist, $media" } else { set medialist "$medialist and $media" } } if {$ldata($aid,medianum)==1} { set desc "$desc\nThe session medium is $medialist." } else { set desc "$desc\nSession media are $medialist." } return $desc } proc cli_detail_session {ix} { global ldata set aid [cli_map_ix_to_aid $ix] if {$aid==0} return cli_describe_session $ix for {set i 0} {$i < $ldata($aid,medianum)} {incr i} { set media $ldata($aid,$i,media) puts "The $media protocol is $ldata($aid,$i,proto), format is [get_fmt_name $ldata($aid,$i,fmt)], address is $ldata($aid,$i,addr) on port $ldata($aid,$i,port) with TTL $ldata($aid,$i,ttl)." } } proc cli_new_session {aid} { global cli_mode cli_prompt cli_explain cli_exec cli_variable puts "To abort session creation, enter \"cancel\" at any prompt." set cli_mode text puts "Enter session name and hit Enter:" set cli_variable cli_session set cli_exec "cli_new_description $aid" } proc cli_new_description {aid} { global cli_mode cli_prompt cli_explain cli_exec cli_variable set cli_mode text puts "Enter session description and hit Enter:" set cli_variable cli_desc set cli_exec "cli_new_scope $aid" } proc cli_new_scope {aid} { global cli_mode cli_prompt cli_explain cli_exec cli_variable set cli_mode choose puts "Possible scopes for the session are:" global cli_scopemap set cli_variable cli_scopemap set cli_prompt "Enter a scope number:" set cli_explain scope } proc cli_prefs {} { puts "Sorry - this feature is not yet implemented." } set cli_normal_prompt "SDR command? " set cli_prompt $cli_normal_prompt proc cli_prompt {} { global cli_prompt puts "\n$cli_prompt" } proc cli_normal {} { global cli_mode cli_prompt cli_normal_prompt set cli_mode normal set cli_prompt $cli_normal_prompt } proc cli_usage {} { puts "Type \"help\" for a full command summary. SDR commands are:" puts "scan" puts "scan broadcast" puts "scan meeting" puts "scan test" puts "scan unknown" puts "scan active" puts "scan future" puts "show " puts "detail " puts "join " puts "audio " puts "video " puts "whiteboard " puts "create" puts "preferences" } proc cli_help {} { puts "SDR command usage:" puts "help" puts " gives this output." puts "scan" puts " gives a listing of all sessions." puts "scan broadcast" puts " gives a listing of all broadcast type sessions." puts "scan meeting" puts " gives a listing of all meeting type sessions." puts "scan test" puts " gives a listing of all test type sessions." puts "scan unknown" puts " gives a listing of all unknown type sessions." puts "scan active" puts " gives a listing of all sessions scheduled to currently be active." puts "scan future" puts " gives a listing of all future sessions." puts "show " puts " gives a description of the specified session." puts "detail " puts " gives a more detailed description of the specified session." puts "join " puts " starts all the media tools for the specified session." puts "audio " puts " starts only the audio tool for the specified session." puts "video " puts " starts only the audio tool for the specified session." puts "whiteboard " puts " starts only the whiteboard tool for the specified session." puts "create" puts " creates a new session and announces it." puts "preferences" puts " sets various preferences for how SDR behaves." } proc cli_join_session {media ix} { global ldata set aid [cli_map_ix_to_aid $ix] if {$aid==0} return if {$media=="all"} { set success 1 for {set i 0} {$i < $ldata($aid,medianum)} {incr i} { set success [expr [cli_start_media "$aid" $i "start"]&&$success] } } else { set success 0 set done 0 for {set i 0} {$i < $ldata($aid,medianum)} {incr i} { if {$ldata($aid,$i,media)==$media} { set success [cli_start_media "$aid" $i "start"] set done 1 break } } if {$done==0} { puts "Error: Session $ix does not have media $media" } } } #XXX this should be merged with start_media in start_tools.tcl #this is a quick hack that produces the warnings on stdout instead #of the GUI. proc cli_start_media {aid mnum mode} { global sd_sess ldata set ldata($aid,started) 1 set media $ldata($aid,$mnum,media) set sd_sess(sess_id) $aid set sd_sess(address) $ldata($aid,multicast) set sd_sess(ttl) $ldata($aid,ttl) set sd_sess(name) $ldata($aid,session); set sd_sess(media) "" for {set i 0} {$i < $ldata($aid,medianum)} {incr i} { set sd_sess(media) "$sd_sess(media) $ldata($aid,$i,media)" } set sd_sess(creator) $ldata($aid,creator) set sd_sess(creator_id) $ldata($aid,source) set sd_sess(source_id) $ldata($aid,heardfrom) set sd_sess(arrival_time) $ldata($aid,theard) set sd_sess(start_time) $ldata($aid,starttime) set sd_sess(end_time) $ldata($aid,endtime) set sd_sess(attributes) "" global sd_$media set tmp sd_$media\(attributes\) set $tmp $ldata($aid,$mnum,vars) set tmp sd_$media\(port\) set $tmp $ldata($aid,$mnum,port) set tmp sd_$media\(address\) set $tmp $ldata($aid,$mnum,addr) set tmp sd_$media\(layers\) set $tmp $ldata($aid,$mnum,layers) set tmp sd_$media\(ttl\) set $tmp $ldata($aid,$mnum,ttl) set tmp sd_$media\(proto\) set $tmp $ldata($aid,$mnum,proto) set tmp sd_$media\(fmt\) set $tmp $ldata($aid,$mnum,fmt) set tmp sd_$media\(proto\) set $tmp $ldata($aid,$mnum,proto) set sd_priv($media) 1 if {$mode=="start"} { if {[is_known_media $media]!=-1} { return [cli_start_media_tool $aid $media $ldata($aid,$mnum,proto) $ldata($aid,$mnum,fmt) [split $ldata($aid,$mnum,vars) "\n"]] } else { puts "Media $media unknown." puts "The session you tried to join contains a media \"$media\" that I do not know about. To join this session you need the \"$media\" sdr plug-in module and a media tool capable of joining this session." return 0 } } elseif {$mode=="record"} { return [record_$media] } else { puts stderr "unknown mode to start_media: $mode" return 0 } } #XXX this should be merged with start_media_tool in plugins.tcl #this is a quick hack that produces the warnings on stdout instead #of the GUI. proc cli_start_media_tool {aid media proto fmt attrlist} { global rules global mappings global attrflags global withattrs global tool_state global macrovalues foreach macrovalue [array names macrovalues] { unset macrovalues($macrovalue) } if {([lsearch $rules "$media.$proto.$fmt"]==-1) && \ ([wcsearch $rules "$media.$proto"]=="")} { puts "The session you tried to join contains a media \"$media\" with protocol \"$proto\" and format \"$fmt\". I have no plug-in module that defines a $media tool for this. To join this session you need a plug-in module for this combination of media, protocol and format and a media tool capable of receiving the data." return 0 } else { if {[lsearch $rules "$media.$proto.$fmt"]==-1} { #there were no exact matches on the format, but a wildcard #match was possible (typically an RTP dynamic payload type) set wclist [wcsearch $rules "$media.$proto"] set match 0 # puts $wclist # puts "got a wildcard match" foreach wc $wclist { set needattr "" catch {set needattr $withattrs($media.$proto.*$wc)} if {$needattr==""} { continue } foreach wa $needattr { set withattr [expand_var $wa $wc $fmt] set tmp $withattr # puts $withattr while {[string first "*(" $tmp]!=-1} { set tmp [remove_wc_vars $tmp] } # puts $tmp foreach attr $attrlist { # puts "string match >$tmp< >$attr<" if {[string match $tmp $attr]==1} { set match 1 break } } if {$match==1} { break } } if {$match==1} { break } } if {$match==1} { #at this stage wc holds the name of the wildcard and #wa holds the relevant "withattr" line from the plugin #now we need to match against the actual attributes.. #(this is really ugly) # puts "SUCCESS\nwc:$wc\nwa:$wa" # puts "tmp:$tmp" foreach attrflag [array names attrflags] { # puts "attrflag:$attrflag" # puts "match: *.$media.$proto.*$wc.$wa" if {[string match "*.$media.$proto.\*$wc.$wa" $attrflag]==1} { # puts "flags index: $attrflag" # puts "flags: $attrflags($attrflag)" set tool [find_tool [lindex [split $attrflag "."] 0]] if {$tool==""} { continue } # puts "tool: $tool" set macrovalues([string trim $wc "()"]) $fmt set fmt "*$wc" lappend attrlist $wa set rule $mappings($media.$proto.*$wc) break } } } else { puts "The session you tried to join contains a media \"$media\" with protocol \"$proto\" and format \"$fmt\". I have no plug-in module that defines a $media tool for this. To join this session you need a plug-in module for this combination of media, protocol and format and a media tool capable of receiving the data." return 0 } } else { #we got a format we know we support set rule $mappings($media.$proto.$fmt) } set rulelist {} foreach subrule $rule { set tool [find_tool [lindex $subrule 0]] if {$tool==""} { # catch {puts "the tool [lindex $subrule 0] is not installed"} } else { set tmp enabled # catch {puts "$media.$proto.$fmt.[lindex $subrule 0]"} catch {set tmp $tool_state($media.$proto.$fmt.[lindex $subrule 0])} if {$tmp=="enabled"} { lappend rulelist $subrule } } } if {[llength $rulelist]==0} { set toollist {} foreach subrule $rule { lappend toollist [lindex $subrule 0] } puts "The session you tried to join contains a media \"$media\" for which I can find no suitable tool installed. Suitable tools that I know about would include:\n$toollist\nNone of these is in your command path." # puts "no tools are installed for $media" return 0; } elseif {[llength $rulelist]>1} { # set toollist {} # set newrules {} # foreach rule [list_reverse $rulelist] { # set tool [lindex $rule 0] # if {[lsearch -exact $toollist $tool]>=0} { # #we have two rules for the same tool # #skip this rule # } else { # lappend newrules $rule # } # lappend toollist $tool # } # if {[llength $newrules]>1} { # select_tool_for_media $aid $media $proto $fmt \ # $newrules $attrlist # return 0 # } else { # set rule [lindex $newrules 0] # } cli_select_tool_for_media $aid $media $proto $fmt \ $rulelist $attrlist return 0 } else { set rule [lindex $rulelist 0] } } return [apply_startup_rule $aid $media $proto $fmt $rule $attrlist] } proc cli_select_tool_for_media {aid media proto fmt rulelist attrlist} { global cli_toolmap cli_mode cli_exec cli_explain cli_variable cli_prompt puts "Select the $media tool to use:" set bnum 1 global startrule set startrule($media) [lindex $rulelist 0] foreach rule $rulelist { set cli_toolmap($bnum) $rule puts "$bnum: [lindex $rule 0]" # -variable startrule($media) -value $rule -highlightthickness 0 incr bnum } set cli_mode starttool set cli_exec "apply_startup_rule $aid $media $proto $fmt \"%\" \"$attrlist\"" set cli_explain "tool" set cli_variable cli_toolmap set cli_prompt "Please enter the tool number:" } set cli_mode normal proc cli_parse_command {} { global cli_cmd global cli_mode cli_exec cli_variable cli_explain cli_prompt set line $cli_cmd set cmd [lindex $line 0] if {$cli_mode=="normal"} { switch $cmd { "help" { cli_help } "?" { cli_usage } "scan" { if {[llength $line]>2} {cli_usage} if {[llength $line]==1} { cli_say_sessions all } else { cli_say_sessions [lindex $line 1] } } "show" { if {[llength $line]!=2} {cli_usage} cli_describe_session [lindex $line 1] } "detail" { if {[llength $line]!=2} {cli_usage} cli_detail_session [lindex $line 1] } "join" { if {[llength $line]!=2} {cli_usage} cli_join_session all [lindex $line 1] } "audio" { if {[llength $line]!=2} {cli_usage} cli_join_session audio [lindex $line 1] } "video" { if {[llength $line]!=2} {cli_usage} cli_join_session video [lindex $line 1] } "whiteboard" { if {[llength $line]!=2} {cli_usage} cli_join_session whiteboard [lindex $line 1] } "create" { if {[llength $line]!=1} {cli_usage} cli_new_session } "preferences" { if {[llength $line]!=1} {cli_usage} cli_prefs } "quit" { puts "Goodbye!" exit 0 } default { cli_usage } } } else { global [set cli_variable] if {[info exists [set cli_variable]($cli_cmd)]} { set var [set [set cli_variable]($cli_cmd)] regsub "\%" $cli_exec $var cmd eval $cmd puts "OK." cli_normal } else { puts "Invalid $cli_explain number. Valid $cli_explain numbers are 1 to [llength [array names [set cli_variable]]]." } } cli_prompt } proc select_security_info {win width height} { global prefs frame $win -borderwidth 3 -relief raised frame $win.setw -borderwidth 0 -height 1 -width $width pack $win.setw -side top label $win.l -text [tt "Security Configuration"] pack $win.l -side top frame $win.f pack $win.f -side top -fill both -expand true frame $win.f.l pack $win.f.l -side right -fill both -expand true frame $win.f.l.pad -height 30 pack $win.f.l.pad -side top frame $win.f.l.f -borderwidth 2 -relief groove pack $win.f.l.f -side top -anchor w label $win.f.l.f.title -text "Encryption Group" -relief ridge \ -borderwidth 2 pack $win.f.l.f.title -side top -fill x -expand true label $win.f.l.f.l1 -text "Group name:" pack $win.f.l.f.l1 -side top -anchor w entry $win.f.l.f.e1 -width 40 -relief sunken -borderwidth 1 \ -highlightthickness 0 pack $win.f.l.f.e1 -side top -anchor w label $win.f.l.f.l2 -text "Key:" pack $win.f.l.f.l2 -side top -anchor w password $win.f.l.f.e2 -width 40 -relief sunken -borderwidth 1 \ -variable tmpeditpass pack $win.f.l.f.e2 -side top -anchor w label $win.f.l.f.l2b -text "Re-type Key:" pack $win.f.l.f.l2b -side top -anchor w password $win.f.l.f.e2b -width 40 -relief sunken -borderwidth 1 \ -variable tmpeditpass2 pack $win.f.l.f.e2b -side top -anchor w frame $win.f.l.f.f pack $win.f.l.f.f -side top -anchor w -fill x button $win.f.l.f.f.b2 -text "Modify group" \ -command "select_modify_key $win" -state disabled -pady 1 pack $win.f.l.f.f.b2 -side left -anchor w -fill x -expand true button $win.f.l.f.f.b3 -text "Delete group" \ -command "select_delete_key $win" -state disabled -pady 1 pack $win.f.l.f.f.b3 -side left -anchor w -fill x -expand true frame $win.f.r pack $win.f.r -side left -fill y -expand true label $win.f.r.l -text "Encryption Groups" pack $win.f.r.l -side top frame $win.f.r.f pack $win.f.r.f -side top listbox $win.f.r.f.lb -height 10 -width 20 -yscroll "$win.f.r.f.sb set" \ -relief sunken -borderwidth 1 -selectmode single \ -selectforeground [resource activeForeground] \ -selectbackground [resource activeBackground] \ -highlightthickness 0 bind $win.f.r.f.lb <1> "%W selection clear 0 end;\ %W selection set \[%W nearest %y\];\ show_encryption_group $win" pack $win.f.r.f.lb -side left -fill x button $win.f.r.b -text "Add encryption group" -command register_key pack $win.f.r.b -side top -fill x global keylistbox set keylistbox $win.f.r.f.lb scrollbar $win.f.r.f.sb -command "$win.f.r.f.lb yview" \ -borderwidth 1 pack $win.f.r.f.sb -side right -fill y $win.f.l.f.l1 configure -foreground [resource disabledForeground] $win.f.l.f.e1 configure -state disabled $win.f.l.f.l2 configure -foreground [resource disabledForeground] $win.f.l.f.e2 configure -state disabled $win.f.l.f.l2b configure -foreground [resource disabledForeground] $win.f.l.f.e2b configure -state disabled $win.f.l.f.f.b2 configure -state disabled if {[get_passphrase]==""} { $win.f.r.l configure -foreground [resource disabledForeground] set keyfile "[glob -nocomplain [resource sdrHome]]/keys" if {[file exists $keyfile]&&([file size $keyfile]>0)} { $win.f.r.b configure -state disabled } } frame $win.f2 -borderwidth 0 -relief flat -width 1 -height \ [expr $height - [winfo reqheight $win]] pack $win.f2 -side top show_keys prefs } proc show_keys {win} { global keylist keylistbox catch { if {$win == "prefs"} { set win $keylistbox } $win delete 0 end foreach keyname $keylist { $win insert end "$keyname" } } } proc clear_keys {win} { global keylistbox catch { if {$win == "prefs"} { set win $keylistbox } $win delete 0 end } } proc show_encryption_group {win} { set sel [$win.f.r.f.lb curselection] if {$sel==""} return set keyname [string trimright [$win.f.r.f.lb get $sel] "\n"] set tmp [find_key_by_name $keyname] set key [lindex $tmp 0] $win.f.l.f.l1 configure -foreground [resource foreground] $win.f.l.f.e1 configure -state normal \ -background [resource entryBackground] $win.f.l.f.l2 configure -foreground [resource foreground] $win.f.l.f.e2 configure -state normal \ -background [resource entryBackground] $win.f.l.f.l2b configure -foreground [resource foreground] $win.f.l.f.e2b configure -state normal \ -background [resource entryBackground] $win.f.l.f.e1 delete 0 end $win.f.l.f.e1 insert 0 $keyname $win.f.l.f.e2.workaround set $key $win.f.l.f.e2b.workaround set $key $win.f.l.f.f.b2 configure -state normal $win.f.l.f.f.b3 configure -state normal } proc select_delete_key {win} { set sel [$win.f.r.f.lb curselection] if {$sel==""} return set keyname [string trimright [$win.f.r.f.lb get $sel] "\n"] clear_prefs_keys delete_key $keyname $win.f.l.f.e1 delete 0 end $win.f.l.f.e2.workaround set "" $win.f.l.f.e2b.workaround set "" $win.f.l.f.f.b2 configure -state disabled $win.f.l.f.f.b3 configure -state disabled $win.f.l.f.l1 configure -foreground [resource disabledForeground] $win.f.l.f.e1 configure -state disabled -background [resource background] $win.f.l.f.l2 configure -foreground [resource disabledForeground] $win.f.l.f.e2 configure -state disabled -background [resource background] $win.f.l.f.l2b configure -foreground [resource disabledForeground] $win.f.l.f.e2b configure -state disabled -background [resource background] } proc select_modify_key {win} { global tmpeditpass tmpeditpass2 keylistbox set sel [$win.f.r.f.lb curselection] if {$sel==""} { bell prefs_help "No group to replace is selected in the encryption groups list" after 3000 prefs_help "\"\"" return } set keyname [string trimright [$win.f.r.f.lb get $sel] "\n"] set newkeyname [$win.f.l.f.e1 get] if {[string compare $tmpeditpass $tmpeditpass2]!=0} { bell prefs_help "You must enter the same key twice" after 3000 prefs_help "\"\"" return } if {[string length $tmpeditpass]<8} { bell prefs_help "Encryption keys must be at least 8 characters" after 3000 prefs_help "\"\"" return } clear_prefs_keys delete_key $keyname clear_prefs_keys add_key $tmpeditpass $newkeyname save_keys unset tmpeditpass unset tmpeditpass2 $win.f.l.f.e1 delete 0 end $win.f.l.f.e2.workaround set "" $win.f.l.f.e2b.workaround set "" $win.f.l.f.f.b2 configure -state disabled $win.f.l.f.f.b3 configure -state disabled $win.f.l.f.l1 configure -foreground [resource disabledForeground] $win.f.l.f.e1 configure -state disabled -background [resource background] $win.f.l.f.l2 configure -foreground [resource disabledForeground] $win.f.l.f.e2 configure -state disabled -background [resource background] $win.f.l.f.l2b configure -foreground [resource disabledForeground] $win.f.l.f.e2b configure -state disabled -background [resource background] focus $keylistbox } proc register_key {} { catch {destroy .key} toplevel .key wm title .key "Sdr: Enter a new encryption key" frame .key.f -relief groove -borderwidth 2 pack .key.f -side top label .key.f.l1 -text "Name of encryption group:" pack .key.f.l1 -side top -anchor w entry .key.f.e1 -width 60 -background [option get . entryBackground Sdr] \ -highlightthickness 0 pack .key.f.e1 -side top -anchor w frame .key.f.f pack .key.f.f -side top frame .key.f.f.l pack .key.f.f.l -side left label .key.f.f.l.l -text "Encryption key (at least 8 characters):" pack .key.f.f.l.l -side top -anchor w password .key.f.f.l.e -width 30 -variable tmpkey \ -background [option get . entryBackground Sdr] pack .key.f.f.l.e -side top -anchor w frame .key.f.f.r pack .key.f.f.r -side left label .key.f.f.r.l -text "Encryption key: (again)" pack .key.f.f.r.l -side top -anchor w password .key.f.f.r.e -width 30 -variable tmpkey2 \ -background [option get . entryBackground Sdr] pack .key.f.f.r.e -side top -anchor w # frame .key.f.f1 # pack .key.f.f1 -side top # new_mk_session_admin .key.f.f1.admin new admin label .key.f.msg -borderwidth 1 -relief raised pack .key.f.msg -side top -fill x -expand true frame .key.f.f2 pack .key.f.f2 -side top -fill x -expand true button .key.f.f2.ok -text "OK" -command submit_key pack .key.f.f2.ok -side left -fill x -expand true button .key.f.f2.cancel -text "Cancel" -command {destroy .key} pack .key.f.f2.cancel -side left -fill x -expand true } proc submit_key {} { global keylist tmpkey tmpkey2 if {[string length [.key.f.e1 get]]<2} { bell .key.f.msg configure -text "You must configure a name for the encryption group" after 3000 "catch {.key.f.msg configure -text \"\"}" return } if {[string compare $tmpkey $tmpkey2]!=0} { .key.f.msg configure -text "You have not entered the same key twice" after 3000 "catch {.key.f.msg configure -text \"\"}" return } if {[string length $tmpkey]<8} { bell .key.f.msg configure -text "Encryption keys must be at least 8 characters" after 3000 "catch {.key.f.msg configure -text \"\"}" return } add_key $tmpkey [.key.f.e1 get] unset tmpkey catch {destroy .key} #this will get re-installed by the re-load that happens after saving... set keylist "" #this is needed to allow the first key to be shown on freeBSD save_prefs if {[get_passphrase] == ""} { enter_long_passphrase save } else { save_keys } } proc query_passphrase { win } { catch {destroy .qpass} toplevel .qpass global querypass wm title .qpass "Sdr: Enter the pass phrase for your key file" frame .qpass.f -relief groove -borderwidth 2 pack .qpass.f -side top message .qpass.f.m -text "You must enter your passphrase to be able to load your encryption keys." -aspect 600 pack .qpass.f.m -side top frame .qpass.f.f pack .qpass.f.f -side top -fill x -expand true label .qpass.f.f.l -text "Password:" pack .qpass.f.f.l -side left -anchor e -fill x -expand true password .qpass.f.f.e -width 40 -variable querypass \ -background [option get . entryBackground Sdr] pack .qpass.f.f.e -side left bind .qpass.f.f.e "submit_qpass .qpass $win .qpass.f.msg \"\"" label .qpass.f.msg -borderwidth 1 -relief raised pack .qpass.f.msg -side top -fill x -expand true frame .qpass.f.f2 pack .qpass.f.f2 -side top -fill x -expand true button .qpass.f.f2.ok -text "OK" \ -command "submit_qpass .qpass $win .qpass.f.msg \"\"" pack .qpass.f.f2.ok -side left -fill x -expand true button .qpass.f.f2.cancel -text "Cancel" -command "destroy_query .qpass" pack .qpass.f.f2.cancel -side left -fill x -expand true } proc destroy_query { win } { global security set security public catch {destroy $win} } proc submit_qpass { qwin createwin msgwin str } { global querypass set_passphrase $querypass $msgwin configure -text "Checking passphrase" update if {[load_keys]==1} { show_keys $createwin.enc.keys.lb $msgwin configure -text "Loading cached sessions" load_from_cache_crypt $msgwin configure -text "$str" } else { bell $msgwin configure -text "Pass phrase incorrect" set querypass "" after 3000 "catch {$msgwin configure -text \"$str\"}" return } catch {destroy $qwin} catch {destroy .f5} } proc enter_passphrase {} { global ifstyle if {$ifstyle(labels)=="long"} { enter_long_passphrase load } else { pack .f4 -side top -fill both -expand true -after .f2 enter_short_passphrase .f5 .f4 } } proc enter_long_passphrase {mode} { catch {destroy .pass} toplevel .pass wm title .pass "Sdr: Enter the pass phrase for your key file" frame .pass.f -relief groove -borderwidth 2 pack .pass.f -side top message .pass.f.m -text "You must enter a passphrase to be able to load and save the keys for encrypted sessions." -aspect 600 pack .pass.f.m -side top frame .pass.f.f pack .pass.f.f -side top frame .pass.f.f.f0 pack .pass.f.f.f0 -side top -fill x -expand true label .pass.f.f.f0.l -text "Password:" pack .pass.f.f.f0.l -side left -anchor e -fill x -expand true password .pass.f.f.f0.e -width 40 -variable tmppass \ -background [option get . entryBackground Sdr] pack .pass.f.f.f0.e -side left ##ed bind .pass.f.f.f0.e "submit_pass .pass $mode .pass.f.msg \"\"" bind .pass.f.f.f0.e "submit_pass .pass $mode .pass.f.msg \"\"" # only want to retype passphrase if saving the keys file for the first time if { $mode == "save" } { frame .pass.f.f.f1 pack .pass.f.f.f1 -side top -fill x -expand true label .pass.f.f.f1.l -text "Retype Password:" pack .pass.f.f.f1.l -side left -anchor e -fill x -expand true password .pass.f.f.f1.e -width 40 -variable tmppass1 \ -background [option get . entryBackground Sdr] pack .pass.f.f.f1.e -side left bind .pass.f.f.f1.e "submit_pass .pass $mode .pass.f.msg \"\"" } label .pass.f.msg -borderwidth 1 -relief raised pack .pass.f.msg -side top -fill x -expand true frame .pass.f.f2 pack .pass.f.f2 -side top -fill x -expand true button .pass.f.f2.ok -text "OK" \ -command "submit_pass .pass $mode .pass.f.msg \"\"" pack .pass.f.f2.ok -side left -fill x -expand true button .pass.f.f2.cancel -text "Cancel" -command "destroy_pass .pass $mode" pack .pass.f.f2.cancel -side left -fill x -expand true } proc destroy_pass {win mode} { global tmpkey2 # destroy key which has been created and saved even though no passphrase # entered and now cancelled from passphrase screen # only want to remove key if we are cancelling from a save keyfile for the # first time rather than a load keys at startup with Long labels selected if {$mode == "save"} { set tmpdel [find_keyname_by_key $tmpkey2] set delkey [lindex $tmpdel 0] clear_prefs_keys delete_key $delkey unset tmpkey2 } # destroy passphrase window catch {destroy $win} } proc enter_short_passphrase {win after} { frame $win -relief groove -borderwidth 2 pack $win -side top -after $after -fill x set str "Enter passphrase to view encrypted sessions:" label $win.msg -borderwidth 1 -text $str\ -font [option get . infoFont Sdr] -anchor nw pack $win.msg -side top -fill x -expand true frame $win.f pack $win.f -side top -fill x -expand true # entry $win.f.e -width 30 -font [option get . infoFont Sdr] \ -background [option get . entryBackground Sdr] password $win.f.e -width 30 -font [option get . infoFont Sdr] \ -background [option get . entryBackground Sdr] -variable tmppass \ -command "submit_pass $win load $win.msg \"$str\"" pack $win.f.e -side left -fill x -expand true # bind $win.f.e "submit_pass $win load" } proc submit_pass {win mode msgwin str} { global tmppass tmppass1 ifstyle # if {[string length [$win.f.e get]]<8} \{ if {([string length $tmppass]<8)&&($mode == "save")} { bell $msgwin configure -text "Please choose a longer pass phrase" after 5000 "catch {$win.f.msg configure -text $str}" return } if { $mode == "save" } { if { [string compare $tmppass $tmppass1]!=0 } { bell $msgwin configure -text "You have not entered the same password twice" after 3000 "catch {.$win.f.msg configure -text \"\"}" return } } # set_passphrase [$win.f.e get] set_passphrase $tmppass if {$mode == "save"} { save_keys } elseif {$mode == "load"} { $msgwin configure -text "Checking passphrase" update if {[load_keys]==1} { $msgwin configure -text "Loading cached sessions" update load_from_cache_crypt $msgwin configure -text "$str" } else { if {$ifstyle(labels)=="long"} { $win.f.f.f0.e.workaround set "" } else { $win.f.e.workaround set "" } bell $msgwin configure -text "Pass phrase incorrect" set tmppass "" after 3000 "catch {$msgwin configure -text \"$str\"}" return } } catch {destroy $win} } set keylist "" proc clear_prefs_keys {} { global keylist set keylist "" show_keys prefs } proc install_key {keyname} { global keylist lappend keylist $keyname show_keys prefs } proc new_mk_session_security {win aid} { global ldata security keylist user_id key_id global enc_old_key_sel auth_old_key_sel asympass asympse if {[winfo exists $win]==0} { frame $win -relief groove -borderwidth 2 # Authentication code [dlh] # Creates a button to select the authentication type and a text box # for selecting the required (PGP)key. frame $win.auth frame $win.auth.sel label $win.auth.sel.lauth -text "Authentication:" menubutton $win.auth.sel.mauth -menu $win.auth.sel.mauth.menu -width 10 -borderwidth 1 -relief raised menu $win.auth.sel.mauth.menu -tearoff 0 $win.auth.sel.mauth.menu add command -label "None"\ -command "set_auth_type $win none" $win.auth.sel.mauth.menu add command -label "PGP"\ -command "set_auth_type $win pgp" $win.auth.sel.mauth.menu add command -label "X509"\ -command "set_auth_type $win x509" $win.auth.sel.mauth.menu add command -label "PGP+CERT"\ -command "set_auth_type $win cpgp" $win.auth.sel.mauth.menu add command -label "X509+CERT"\ -command "set_auth_type $win cx50" frame $win.auth.keys text $win.auth.keys.lb -width 15 -height 5 -relief flat\ -relief sunken -borderwidth 1 -yscroll "$win.auth.keys.ysb set"\ -highlightthickness 0 scrollbar $win.auth.keys.ysb -command "$win.auth.keys.lb yview" -borderwidth 1 -highlightthickness 0 frame $win.auth.pwd label $win.auth.pwd.l -text "Password For PGP:" label $win.auth.pwd.m -text "Passphrase:" password $win.auth.pwd.e -width 30 -relief sunken\ -variable asympass -borderwidth 1\ -background [option get . entryBackground Sdr] if {$aid=="new"} { set_auth_type $win none set auth_old_key_sel "" } else { # We are modifying an announcement so display old state of # authentication and encryption selection set asym $ldata($aid,authtype) set key_id($asym,auth_cur_key_sel) $ldata($aid,asym_keyid) set auth_old_key_sel $ldata($aid,asym_keyid) set_auth_type $win $ldata($aid,authtype) # puts "Advert id: $aid" # puts "Auth Type: $ldata($aid,authtype)" } frame $win.enc frame $win.enc.sel label $win.enc.sel.lenc -text "Encryption:" menubutton $win.enc.sel.menc -menu $win.enc.sel.menc.menu -width 10 -borderwidth 1 -relief raised menu $win.enc.sel.menc.menu -tearoff 0 $win.enc.sel.menc.menu add command -label "None"\ -command "set_enc_type $win none $aid" $win.enc.sel.menc.menu add command -label "Des"\ -command "set_enc_type $win des $aid" $win.enc.sel.menc.menu add command -label "PGP"\ -command "set_enc_type $win pgp $aid" $win.enc.sel.menc.menu add command -label "X509"\ -command "set_enc_type $win x509 $aid" frame $win.enc.keys listbox $win.enc.keys.lb -width 15 -height 5 -yscroll\ "$win.enc.keys.ysb set" -relief sunken -borderwidth 1 \ -selectmode single -selectforeground [resource activeForeground] \ -selectbackground [resource activeBackground] \ -highlightthickness 0 #text $win.enc.keys.lb -width 15 -height 5 -relief flat\ # -relief sunken -borderwidth 1 -yscroll "$win.enc.keys.ysb set"\ # -highlightthickness 0 scrollbar $win.enc.keys.ysb\ -command "$win.enc.keys.lb yview" -borderwidth 1 -highlightthickness 0 if {$keylist==""} { #$win.enc.keys.lb configure -state disabled set security public } if {$aid=="new"} { set_enc_type $win none $aid set enc_old_key_sel "" set ldata($aid,key) "" set security public } else { if {([string compare $aid "new"]!=0)&&($ldata($aid,key)!="")} { set security private } else { set security public } # We are modifying an announcement so display old state of # authentication and encryption selection set asym $ldata($aid,enctype) set key_id($asym,enc_cur_key_sel) $ldata($aid,enc_asym_keyid) set enc_old_key_sel $ldata($aid,enc_asym_keyid) set_enc_type $win $ldata($aid,enctype) $aid # puts "Advert id: $aid" # puts "Enc Type: $ldata($aid,enctype)" } } pack $win -side left -fill both -expand true pack $win.auth -side top -fill both -expand true pack $win.auth.sel -side top -pady 5 -fill both -expand true pack $win.auth.sel.lauth $win.auth.sel.mauth -anchor nw -side left -padx 5 pack $win.auth.keys -side top -pady 2 -fill both -expand true pack $win.auth.keys.lb -side left -fill both -expand true pack $win.auth.keys.ysb -side right -fill y pack $win.auth.pwd -side top -pady 2 -fill both -expand true pack $win.auth.pwd.l -side top -anchor w pack $win.auth.pwd.m -side top -anchor w pack $win.auth.pwd.e -side top -anchor w pack $win.enc -side top -fill both -expand true pack $win.enc.sel -side top -pady 5 -fill both -expand true pack $win.enc.sel.lenc $win.enc.sel.menc -anchor nw -side left -padx 5 pack $win.enc.keys -side top -pady 2 -fill both -expand true pack $win.enc.keys.lb -side left -fill both -expand true pack $win.enc.keys.ysb -side right -fill y } proc enc_show_keys {win aid} { global keylist security set keyfile "[glob -nocomplain [resource sdrHome]]/keys" if {([file exists $keyfile] == 0)} { #$win.enc.keys.lb configure -state disabled } toggle_security $win if {([string compare $aid "new"]!=0)&&($ldata($aid,key)!="")} { update global keylist set ctr 0 foreach keyname $keylist { set key [lindex [find_key_by_name $keyname] 0] if {[string compare $key $ldata($aid,key)]==0} { $win.enc.keys.lb selection set $ctr break } incr ctr } } } proc get_new_session_key { } { set selkey [.new.f.f.security.enc.keys.lb curselection] if {$selkey==""} { errorpopup "No Key Selected" "You must select a key for encryption" log "user selected no key" return 0 } .new.f.f.security.enc.keys.lb get [lindex $selkey 0] } proc toggle_security {win} { global security if {$security=="public"} { clear_keys $win.enc.keys.lb } else { if {[get_passphrase]==""} { query_passphrase $win } else { show_keys $win.enc.keys.lb } } } proc pref_security {cmd {arg1 {}} {arg2 {}} {arg3 {}}} { global prefs switch $cmd { copyin { } copyout { } defaults { } create { select_security_info $arg1 $arg2 $arg3 return "Security" } balloon { return "Specify encryption keys for private sessions" } save { } } } #If you need to add more panels, create a function called #new_wiz_panel_XYZ, and add XYZ to these lists in the order you want it #called. set new_wiz_norm_panels \ "info type timing_norm scope_norm media_norm contact security accept" set new_wiz_tech_panels \ "info type timing_tech scope_tech media_tech contact security accept" proc create {} { global ttl dayix durationix send zone global timeofday minoffset hroffset media_attr media_fmt media_proto global media_layers medialist new_createtime sess_type global rtp_payload sdrversion security global mediaenc security #AUTH global auth_type global enc_type global sess_auth_status global sess_enc_status global user_id asympass key_id global validpassword global validauth global validfile global validkey log "creating a session" if {$ttl==0} { set ttl [.new.f.f.f3.rr.f.e get] } if {($ttl < 0)|($ttl > 255)} { errorpopup "Illegal Scope Value" "Scope value must be between 0 and 255" log "user had entered an illegal scope value" return } set sess "v=0" set sess "$sess\no=[getusername] $new_createtime [unix_to_ntp [gettimeofday]] IN IP4 [gethostname]" set sess "$sess\ns=[get_new_session_name .new.f.f]" if {[get_new_session_name .new.f.f]==""} { errorpopup "No Session Name" "You must give the session a name" log "user had entered no session name" return 0 } if {[get_new_session_desc]==""} { errorpopup "No Session Description" "You must give some description of your session" log "user had entered no session description" return 0 } set desc [get_new_session_desc] regsub -all "\n" $desc " " desc set sess "$sess\ni=$desc" set uri [get_new_session_uri] if {$uri!=""} { set sess "$sess\nu=$uri" } set email [.new.f.f.you.f0.e get] set phone [.new.f.f.you.f1.e get] if {$email!=""} { set sess "$sess\ne=$email" } if {$phone!=""} { set sess "$sess\np=$phone" } foreach i {1 2 3} { #the catch is here because the simple i/f only has one time entry catch { set tmp [get_expiry_time .new.f.f.f2.act.fb$i $i .new.f.f.f2.act.fd.duration] if {[lindex $tmp 0]!=0} { set starttime [lindex $tmp 0] set stoptime [lindex $tmp 1] set sess "$sess\nt=[format %u $starttime] [format %u $stoptime]" if {[lindex $tmp 2]!=0} { set sess "$sess\nr=[lrange $tmp 2 end]" } } } } set sess "$sess\na=tool:sdr $sdrversion" set sess "$sess\na=type:$sess_type" foreach media $medialist { if {$send($media)==1} { if {([get_new_session_port $media]<1024)|([get_new_session_port $media]>65535)} { errorpopup "Bad $media port number" \ [tt "Port numbers should be between 1024 and 65535"] log "user had entered a bad port number" return 0 } if { $mediaenc($media) == 1 } { # check length of media key if { [ string length [get_new_media_key $media] ] < 8 } { errorpopup "$media key too short" \ [tt "Encryption keys must be at least 8 characters"] log "user had entered short key for $media" return 0 } # the following cause problems inside sdr: \ / " # the following cause problems from command line outside sdr: $ ` # the following (as well as $) are tcl special characters: [ ] # disallow all so that people can join sessions using sdr and via command line if { [string first "\\" "[get_new_media_key $media]" ] != -1 || [string first "/" "[get_new_media_key $media]" ] != -1 || [string first "\"" "[get_new_media_key $media]" ] != -1 || [string first "`" "[get_new_media_key $media]" ] != -1 || [string first "$" "[get_new_media_key $media]" ] != -1 || [string first "\[" "[get_new_media_key $media]" ] != -1 || [string first "\]" "[get_new_media_key $media]" ] != -1 } { errorpopup "$media key has forbidden characters" \ [tt "Encryption keys should not contain \\, /, \", \`, $, \[ or \] as these may cause problems when starting the tools "] log "user had entered forbidden characters in key for $media, key was [get_new_media_key $media] ] " return 0 } } if {$media_proto($media)=="rtp"} { set sess "$sess\nm=$media [get_new_session_port $media] RTP/AVP $rtp_payload(pt:$media_fmt($media))" } else { set sess "$sess\nm=$media [get_new_session_port $media] $media_proto($media) $media_fmt($media)" } if {[valid_mcast_address [get_new_session_addr $media]]==0} { errorpopup "Invalid Multicast Address" \ "The multicast address specified is not a valid IP Class D address" log "user had entered an invalid multicast address" return 0 } set sess "$sess\nc=IN IP4 [get_new_session_addr $media]/$ttl" if {$media_layers($media)>1} { set sess "$sess/$media_layers($media)" } if { $mediaenc($media) == 1 } { set sess "$sess\nk=clear:[get_new_media_key $media]" } foreach attr [array names media_attr] { set m [lindex [split $attr ","] 0] set a [lindex [split $attr ","] 1] if {$m==$media} { if {$media_attr($attr)==1} { set sess "$sess\na=$a" } elseif {($media_attr($attr)!=0)&&\ ($media_attr($attr)!="")} { set sess "$sess\na=$a:$media_attr($attr)" } } } } } # puts "$sess send to $zone(sap_addr,$zone(cur_zone)) $zone(sap_port,$zone(cur_zone)) $ttl" if {[info exists security]&&($security == "private")} { set keyname [string trim [get_new_session_key] "\n"] if {$keyname==0} {return 0}; log "new session was encrypted" } else { set keyname "" log "new session was not encrypted" } # createsession "$sess\n" [ntp_to_unix $stoptime] $zone(sap_addr,$zone(cur_zone)) $zone(sap_port,$zone(cur_zone)) $ttl $keyname #AUTH - ensure passphrase entered if auth key selected if { ($auth_type == "pgp" || $auth_type == "cpgp" || $auth_type =="none") } { set aauth "pgp" } if { ($auth_type == "x509" || $auth_type == "cx50" ) } { set aauth "x509" } if { $enc_type == "pgp" || $enc_type == "none" || $enc_type=="des"} { set asym "pgp" } if { $enc_type == "x509" || $enc_type == "none"} { set asym "x509" } if { ($user_id(pgp,auth_cur_key_sel)!="") &&\ $asympass=="" } { errorpopup "No Passphrase!"\ "The passphrase for $user_id(pgp,auth_cur_key_sel) must be\ entered before authentication information can be \ constructed for this session announcement." log "User did not enter a passphrase for key certificate" return 0 } set validpassword 0 set validauth 0 set validfile 0 set validkey 0 #authentication only createsession "$sess\n" [ntp_to_unix $stoptime] $zone(sap_addr,$zone(cur_zone)) $zone(sap_port,$zone(cur_zone)) $ttl $keyname $auth_type $key_id(pgp,auth_cur_key_sel) #authentication and Encryption createsession "$sess\n" [ntp_to_unix $stoptime] $zone(sap_addr,$zone(cur_zone)) $zone(sap_port,$zone(cur_zone)) $ttl $keyname $auth_type $enc_type $key_id($aauth,auth_cur_key_sel) $key_id($asym,enc_cur_key_sel) if {$validpassword==0 && ($auth_type =="pgp" || $auth_type =="cpgp" )} { errorpopup "Bad Passphrase" "You entered the wrong passphrase for\ $user_id($aauth,auth_cur_key_sel). Try again." log "User entered an incorrect passphrase for key certificate" return 0 } if {$validpassword==0 && ($auth_type =="x509" || $auth_type =="cx50" )} { errorpopup "Secude failed" "The Signed DATA Failed for USER\ $user_id($aauth,auth_cur_key_sel). Try again." log "User entered an incorrect passphrase for key certificate" return 0 } if {$validauth==0 && ($auth_type =="pgp" || $auth_type=="x509" || $auth_type =="cpgp" || $auth_type =="cx50" )} { errorpopup "Length" "Authentication Lenght very big for the Sap session\ $user_id($aauth,auth_cur_key_sel). Try again." log "User entered an incorrect ling Cert for key certificate" return 0 } if {$validfile==0 && ($enc_type =="pgp" || $enc_type=="x509")} { errorpopup "File not created" "Probably public key is missing\ $user_id($aauth,auth_cur_key_sel). Try again." log "Cnnot create file on SDR home directory" return 0 } update after 3000 write_cache log "new session announced at [getreadabletime]" return 1 } # ------------------------------------------------------------ # start of this part of PGP AUTHentication code (AUTH) # ------------------------------------------------------------ proc set_auth_type {win type} { global auth_type global cert set auth_type $type switch $type { none { $win.auth.sel.mauth configure -text None set cert "0" clear_asym_keys $win x509 clear_asym_keys $win pgp } pgp { clear_asym_keys $win x509 clear_asym_keys $win pgp $win.auth.sel.mauth configure -text PGP show_pgp_keys $win } x509 { clear_asym_keys $win x509 clear_asym_keys $win pgp set cert "cert" $win.auth.sel.mauth configure -text X509 show_pkcs7_keys $win } cpgp { clear_asym_keys $win x509 clear_asym_keys $win pgp $win.auth.sel.mauth configure -text PGP+CERT show_pgp_keys $win } cx50 { clear_asym_keys $win x509 clear_asym_keys $win pgp $win.auth.sel.mauth configure -text X509+CERT set cert "path" show_pkcs7_keys $win } other { $win.auth.sel.mauth configure -text Unspecified } } } # ------------------------------------------------------------ # end of this part of PGP AUTHentication code (AUTH) # ------------------------------------------------------------ proc set_enc_type {win type aid} { global enc_type security set enc_type $type switch $type { none { $win.enc.sel.menc configure -text None enc_clear_asym_keys $win x509 enc_clear_asym_keys $win pgp set security public clear_keys $win } des { enc_clear_asym_keys $win x509 enc_clear_asym_keys $win pgp clear_keys $win $win.enc.sel.menc configure -text Des set security private enc_show_keys $win $aid } pgp { set security public enc_clear_asym_keys $win x509 enc_clear_asym_keys $win pgp clear_keys $win $win.enc.sel.menc configure -text PGP enc_pgp_get_key_list $win $aid } x509 { set security public enc_clear_asym_keys $win x509 enc_clear_asym_keys $win pgp $win.enc.sel.menc configure -text X509 enc_show_x509_keys $win $aid } other { set security public $win.enc.sel.menc configure -text Unspecified } } proc do_ad_creation {aid} { global auth_old_key_sel key_id global enc_old_key_sel if {[string compare $auth_old_key_sel $key_id(pgp,auth_cur_key_sel)]==0 || [string compare $enc_old_key_sel $key_id(pgp,enc_cur_key_sel)]==0} { ui_stop_session_ad $aid destroy .new } else { destroy .new } } } proc new_wiz_panel_security {panelnum panels aid} { new_wiz_change_panels .new.f.l configure -text "Step $panelnum: Select security parameters for this session" .new.f.t insert 1.0 "You need to specify the security of session." set next_panel [expr $panelnum + 1] set back_panel [expr $panelnum - 1] .new.f.b.next configure -state normal -command "new_wiz_panel_[lindex $panels $next_panel] $next_panel \"$panels\" $aid" .new.f.b.back configure -state normal -command "new_wiz_panel_[lindex $panels $back_panel] $back_panel \"$panels\" $aid" .new.f.b.accept configure -state disabled new_mk_session_security .new.f.f.security $aid } # AUTH start # --------------------------------------------------------------------- proc show_pgp_keys {win} { $win.auth.pwd.e configure -state normal pgp_get_key_list $win } proc clear_asym_keys {win type} { global user_id global key_id set key_id($type,auth_cur_key_sel) "" set user_id($type,auth_cur_key_sel) "" $win.auth.keys.lb configure -state normal $win.auth.keys.lb delete 1.0 end $win.auth.pwd.l configure -text "" -font [resource infoFont] $win.auth.pwd.e delete 0 end $win.auth.pwd.e configure -state disabled } # --------------------------------------------------------------------- # SYMT end # --------------------------------------------------------------------- proc enc_clear_asym_keys {win type} { global user_id global key_id set key_id($type,enc_cur_key_sel) "" set user_id($type,enc_cur_key_sel) "" # $win.enc.keys.lb configure -state normal $win.enc.keys.lb delete 0 end } proc enc_pgp_get_key_list {win aid} { global no_of_keys global user_id global key_id global sig_id global ldata global env #putlogfile "enc_pgp_get_key_list" set pgpdir "[glob -nocomplain ~]/.pgp" if [info exists env(PGPPATH)] { set env(PGPPATH) $env(PGPPATH) } else { if { [file isdirectory $pgpdir ] == 0} { if { [ enter_pgp_path] == 0 } { return 0 } } else { set env(PGPPATH) $pgpdir } } #set testpgp $testdir/pgp set tclcmd [ list exec pgp -kv ] set result [ catch $tclcmd keylist ] #putlogfile " $env(PGPPATH) $tclcmd $keylist" if {$result == 0} { putlogfile "Cannot open key-file \n" if { [ enter_pgp_path ] == 0} { return 0 } else { enc_pgp_get_key_list $win $aid } } else { # Extract the user id and key id of each key found in the local # PGP public key-ring. set keylist [split $keylist "\n"] set i 0 $win.enc.keys.lb delete 0 end foreach line $keylist { if [regexp {^(pub|sec) +[0-9]+/([0-9A-F]+) [0-9/]+ (.*)$} \ $line {} sigid keyid userid] { set user_id(pgp,$i) $userid set key_id(pgp,$i) $keyid set sig_id(pgp,$i) $sigid if { [string length $userid] > 60 } { set dotdot "..." } else { set dotdot "" } set keyn [string range $userid 0 60]$dotdot #$win.enc.keys.lb delete $i end $win.enc.keys.lb insert $i "$keyn" incr i } } set no_of_keys $i bind $win.enc.keys.lb <1> "%W selection clear 0 end;\ %W selection set \[%W nearest %y\];\ [ format { global no_of_keys global user_id key_id set selkey [%s.enc.keys.lb curselection] if {$selkey==""} { errorpopup "No Key Selected" "You must select a key for encryption" log "user selected no key" return 0 } %s.enc.keys.lb get [lindex $selkey 0] #%s.enc.keys.lb configure -state normal set pgpkey [lindex $selkey 0] set user_id(pgp,enc_cur_key_sel) $user_id(pgp,$pgpkey) set key_id(pgp,enc_cur_key_sel) $key_id(pgp,$pgpkey) if { [string length $user_id(pgp,enc_cur_key_sel)] > 60} { set dotdot "..." } else { set dotdot "" } } $win $win $win $win] " } if {([string compare $aid "new"]!=0)&&($ldata($aid,enc_asym_keyid)!="")} { for {set i 0} {$i < $no_of_keys} {incr i} { if {[string compare $ldata($aid,enc_asym_keyid) $key_id(pgp,$i)] == 0} { $win.enc.keys.lb selection set $i set user_id(pgp,enc_cur_key_sel) $user_id(pgp,$i) break } } } return } # --------------------------------------------------------------------- # SYMT end # --------------------------------------------------------------------- proc pgp_check_authentication {irand} { update global env global recv_asym_keyid global recv_authstatus global recv_authmessage putlogfile "entered pgp_check authentication: irand = $irand" set local_authtxt_file "[glob -nocomplain [resource sdrHome]]/$irand.txt" set local_authsig_file "[glob -nocomplain [resource sdrHome]]/$irand.sig" set local_key_file "[glob -nocomplain [resource sdrHome]]/$irand.pgp" set pgpdir "[glob -nocomplain ~]/.pgp" if [info exists env(PGPPATH)] { if {[string compare $env(PGPPATH) "none"] == 0 } { set recv_authstatus "failed" set recv_asym_keyid "nonenone" set recv_authmessage "No Key Ring Path" set env(PGPPATH) "none" return 1 } else { set env(PGPPATH) $env(PGPPATH) } } else { if { [file isdirectory $pgpdir ] == 0} { if { [ enter_pgp_path] == 0 } { set recv_authstatus "failed" set recv_asym_keyid "nonenone" set recv_authmessage "No Key Ring Path" set env(PGPPATH) "none" return 1 } } else { set env(PGPPATH) $pgpdir } } putlogfile "pgp_check authentication: env(PGPPATH) = $env(PGPPATH)" set tclcmd [ list exec pgp +batchmode=on $local_authsig_file $local_authtxt_file ] putlogfile "pgp_check_authentication: tclcmd = $tclcmd" set result [ catch $tclcmd output ] #putlogfile "PGPPATH $env(PGPPATH)" putlogfile "output $output" # The error information must be conveyed to the user - more work # required....Need a mechanism to identify the session announcement to # the user. putlogfile "pgp_check_authentication: calling pgp_InterpretOutput $output pgpresult 1" pgp_InterpretOutput $output pgpresult 1 #putlogfile "OK=$pgpresult(ok) summary: $pgpresult(summary)" if {$pgpresult(ok) == 1} { set pgpresult(msg) [pgp_ShortenOutput $pgpresult(msg) $pgpresult(summary) $pgpresult(keyid) $pgpresult(userid) $pgpresult(siglen) $pgpresult(date) $pgpresult(sigdate)] putlogfile "pgp_check_authentication: pgpresult(msg) = $pgpresult(msg)" set recv_authstatus "trustworthy" regsub -all {\"} $pgpresult(msg) {} mess set recv_authmessage $mess set recv_asym_keyid $pgpresult(keyid) putlogfile "pgp_check_authentication: recv_authstatus = $recv_authstatus" putlogfile "pgp_check_authentication: recv_authmessage = $recv_authmessage" putlogfile "pgp_check_authentication: recv_asym_keyid = $recv_asym_keyid" #timedmsgpopup "$pgpresult(msg)\n" "$recv_authstatus" 10000 } else { if { [ file exists $local_key_file ] } { update set oldpgppath $env(PGPPATH) catch { unset env(PGPPATH)} set env(PGPPATH) "[glob -nocomplain [resource sdrHome]]" #putlogfile "NEWPGPPATH $env(PGPPATH)" set localpub "[glob -nocomplain [resource sdrHome]]/pubring.pgp" file copy $local_key_file $localpub set tclcmd [ list exec pgp +batchmode=on $local_authsig_file $local_authtxt_file ] #putlogfile "$tclcmd" set result [ catch $tclcmd output ] #putlogfile "inteoutput $output" pgp_InterpretOutput $output pgpresult 1 #putlogfile "OK=$pgpresult(ok) summary: $pgpresult(summary)" file delete "[glob -nocomplain [resource sdrHome]]/pubring.pgp" catch { unset env(PGPPATH)} set env(PGPPATH) $oldpgppath if {$pgpresult(ok) == 1} { set pgpresult(msg) [pgp_ShortenOutput $pgpresult(msg) $pgpresult(summary) $pgpresult(keyid) $pgpresult(userid) $pgpresult(siglen) $pgpresult(date) $pgpresult(sigdate)] set recv_authstatus "integrity" regsub -all {\"} $pgpresult(msg) {} mess set recv_authmessage $mess set recv_asym_keyid $pgpresult(keyid) # Ask the user if he wants to add the certificate to the publicKey #catch { unset env(PGPPATH)} set pubkey [concat "Would you like to add Public key of \" " $pgpresult(userid) "\"to your public key ring"] regsub -all {\"} $pubkey {} pubkey1 pgp_AddCert $local_key_file "Adding Public Key" "$pubkey1" } else { set pgpresult(msg) [pgp_ShortenOutput $pgpresult(msg) $pgpresult(summary) $pgpresult(keyid) "none" "none" "none" "none" ] # set result [ certExec [list $local_authsig_file $local_authtxt_file ] output $irand] set recv_authstatus "failed" set recv_asym_keyid $pgpresult(keyid) regsub -all {\"} $pgpresult(msg) {} mess set recv_authmessage $mess } # catch { unset env(PGPPATH)} } else { set pgpresult(msg) [pgp_ShortenOutput $pgpresult(msg) $pgpresult(summary) pgpresult(keyid) "none" "none" "none" "none" ] set recv_authstatus "failed" set recv_asym_keyid $pgpresult(keyid) regsub -all {\"} $pgpresult(msg) {} mess set recv_authmessage $mess } } putlogfile "pgp_check_authentication: About to return" putlogfile "pgp_check_authentication: pgpresult(msg) = $pgpresult(msg)" putlogfile "pgp_check_authentication: recv_authstatus = $recv_authstatus" putlogfile "pgp_check_authentication: recv_authmessage = $recv_authmessage" putlogfile "pgp_check_authentication: recv_asym_keyid = $recv_asym_keyid" return 1 } proc pgp_cleanup {irand} { set txtfile "[glob -nocomplain [resource sdrHome]]/$irand.txt" set sigfile "[glob -nocomplain [resource sdrHome]]/$irand.sig" set pgpfile "[glob -nocomplain [resource sdrHome]]/$irand.pgp" putlogfile "entered pgp_cleanup: irand = $irand" if { [file exists $sigfile] } { #putlogfile "pgp_cleanup: attempting to delete $sigfile" file delete $sigfile } if { [file exists $txtfile] } { #putlogfile "pgp_cleanup: attempting to delete $txtfile" file delete $txtfile } if { [file exists $pgpfile] } { #putlogfile "pgp_cleanup: attempting to delete $pgpfile" file delete $pgpfile } } proc enc_pgp_cleanup {irand} { set txtfile "[glob -nocomplain [resource sdrHome]]/$irand.txt" set sigfile "[glob -nocomplain [resource sdrHome]]/$irand.pgp" set pgpfile "[glob -nocomplain [resource sdrHome]]/x$irand" putlogfile "entered enc_pgp_cleanup: irand = $irand" if { [file exists $sigfile] } { #putlogfile "pgp_cleanup: attempting to delete $sigfile" file delete $sigfile } if { [file exists $txtfile] } { #putlogfile "pgp_cleanup: attempting to delete $txtfile" file delete $txtfile } if { [file exists $pgpfile] } { #putlogfile "pgp_cleanup: attempting to delete $pgpfile" file delete $pgpfile } } proc pgp_get_key_list { win } { global no_of_keys global user_id global key_id global sig_id global env set resultkey 0 putlogfile "entered pgp_get_key_list" set pgpdir "[glob -nocomplain ~]/.pgp" if [info exists env(PGPPATH)] { set env(PGPPATH) $env(PGPPATH) } else { if { [file isdirectory $pgpdir ] == 0} { if { [ enter_pgp_path] == 0 } { return 0 } } else { set env(PGPPATH) $pgpdir } } set i 0 set j 0 if { [file exists $env(PGPPATH)/secring.enc] } { if [info exists env(SMARTLOC)] { putlogfile " SMART CARD Being Used" set tclcmd [ list exec pgp -kv $env(PGPPATH)/secring.pgp ] set resultkey [ catch $tclcmd keylist ] pgp_InterpretOutput $keylist pgpresult 1 if {$pgpresult(ok) == 1} { set i 1 set j 1 } else { timedmsgpopup "Secring view error" "Wrong smart card configration" 10000 return 0 } } else { if { [pgp_smart "SMARTCARD" " Place your smartcard" "OK"] == 0 } { set resultkey 0 } else { while { $j == 0} { if { [enter_smart_pse_details] == 0 } { if { [file exists $env(PGPPATH)/secring.pgp] } { set tclcmd [ list exec pgp -kv $env(PGPPATH)/secring.pgp ] set resultkey [ catch $tclcmd keylist ] pgp_InterpretOutput $keylist pgpresult 1 if {$pgpresult(ok) == 1} { set i 1 set j 1 } else { timedmsgpopup "Secring view error" "Wrong smart card configration" 10000 return 0 } } elseif { [file exists $env(PGPPATH)/secring.enc] } { timedmsgpopup "Secring view error" "You need SMART CARD Information" 10000 set j 0 catch { unset env(SMARTLOC)} } else { timedmsgpopup "Secring view error" "You need pgp ring files in $env(PGPPATH)" 10000 catch { unset env(SMARTLOC)} return 0 } } else { set result [Misc_CheckSmart $env(SMARTPIN) $env(SMARTLOC)] while {$i == 0 } { if { $result == 1} { #putlogfile "The SMART pse and pin check OK" set env(USERPIN) $env(SMARTPIN) set tclcmd [ list exec secude pkcs7dec -p $env(SMARTLOC) -i $env(PGPPATH)/secring.enc -o $env(PGPPATH)/secring.pgp] set result [ catch $tclcmd output ] pkcs7_InterpretOutput $output pkcs7result if {$pkcs7result(ok) == 0} { timedmsgpopup "Secring view error" "Wrong smart card configration" 10000 catch {unset env(SMARTLOC)} catch {unset env(SMARTPIN)} set i 1 set j 0 } else { set i 1 set j 1 set tclcmd [ list exec pgp -kv $env(PGPPATH)/secring.pgp ] set resultkey [ catch $tclcmd keylist ] pgp_InterpretOutput $keylist pgpresult 1 if {$pgpresult(ok) == 1} { set i 1 set j 1 } else { set i 1 set j 0 timedmsgpopup "Secring view error" "Wrong smart card configration" 10000 } } } else { catch {unset env(SMARTLOC)} catch {unset env(SMARTPIN)} if {[enter_smart_pse_details ] == 0} { if { [file exists $env(PGPPATH)/secring.pgp] } { set tclcmd [ list exec pgp -kv $env(PGPPATH)/secring.pgp ] set resultkey [ catch $tclcmd keylist ] pgp_InterpretOutput $keylist pgpresult 1 if {$pgpresult(ok) == 1} { set i 1 set j 1 } else { set i 1 set j 0 timedmsgpopup "Secring view error" "Wrong smart card configration" 10000 catch {unset env(SMARTLOC)} catch {unset env(SMARTPIN)} } } elseif { [file exists $env(PGPPATH)/secring.enc] } { timedmsgpopup "Secring view error" "You need SMART CARD Information" 10000 set i 1 set j 0 } else { timedmsgpopup "Secring view error" "You need pgp ring files in $env(PGPPATH)" 10000 return 0 } } else { set result [Misc_CheckSmart $env(SMARTPIN) $env(SMARTLOC) ] } } } } } } } } else { if { [file exists $env(PGPPATH)/secring.pgp] } { set tclcmd [ list exec pgp -kv $env(PGPPATH)/secring.pgp ] set resultkey [ catch $tclcmd keylist ] pgp_InterpretOutput $keylist pgpresult 1 if {$pgpresult(ok) == 1} { set resultkey 1 } else { timedmsgpopup "Secring view error" "Wrong smar t card configration" 10000 return 0 } } else { set resultkey 0 } } #putlogfile "COMMAND= $tclcmd KEYLIST= $keylist" if {$resultkey == 0} { putlogfile "Cannot open key-file \n" if { [ enter_pgp_path] == 0 } { return 0 } else { pgp_get_key_list $win } } else { # Extract the user id and key id of each key found in the local # PGP public key-ring. A modification maybe required here to # ensure that only public-private key pairs are listed. Otherwise # we'll see the keys (belonging to other PGP users) that we have # certified and obviously cannot use for authentication. set keylist [split $keylist "\n"] set i 0 foreach line $keylist { if [regexp {^(pub|sec) +[0-9]+/([0-9A-F]+) [0-9/]+ (.*)$} \ $line {} sigid keyid userid] { set user_id(pgp,$i) $userid set key_id(pgp,$i) $keyid set sig_id(pgp,$i) $sigid if { [string length $userid] > 60 } { set dotdot "..." } else { set dotdot "" } $win.auth.keys.lb insert [expr $i+1].0 \ [string range $userid 0 60]$dotdot $win.auth.keys.lb insert end " \n" $win.auth.keys.lb tag add line$i [expr $i+1].0 \ [expr $i+1].end $win.auth.keys.lb tag configure line$i -background\ [option get . background Sdr] # Set-up bind on key selection $win.auth.keys.lb tag bind line$i <1>\ [format { global no_of_keys for {set i 0} {$i < $no_of_keys} {incr i} { %s.auth.keys.lb tag configure line$i\ -background [option get . background Sdr] } %s.auth.keys.lb tag configure line%s -background\ [option get . activeBackground Sdr] %s.auth.keys.lb configure -state disabled set user_id(pgp,auth_cur_key_sel) $user_id(pgp,%s) set key_id(pgp,auth_cur_key_sel) $key_id(pgp,%s) if { [string length $user_id(pgp,auth_cur_key_sel)] > 60} { set dotdot "..." } else { set dotdot "" } %s.auth.pwd.l configure -text "Enter passphrase\ for [string range $user_id(pgp,auth_cur_key_sel) 0 60]$dotdot" \ -font [resource infoFont] } $win $win $i $win $i $i $win] incr i } } set no_of_keys $i if {$key_id(pgp,auth_cur_key_sel) == ""} { set user_id(pgp,auth_cur_key_sel) $user_id(pgp,0) set key_id(pgp,auth_cur_key_sel) $key_id(pgp,0) set sig_id(pgp,auth_cur_key_sel) $sig_id(pgp,0) } # Need to highlight previously used key in list or, if a new # session is being created, the first key in the list for {set i 0} {$i < $no_of_keys} {incr i} { if {$key_id(pgp,auth_cur_key_sel)==$key_id(pgp,$i)} { $win.auth.keys.lb tag configure line$i -background\ [option get . activeBackground Sdr] set user_id(pgp,auth_cur_key_sel) $user_id(pgp,$i) } } # Restrict how much we display of the user id of each key if { [string length $user_id(pgp,auth_cur_key_sel)] > 60} { set dotdot "..." } else { set dotdot "" } $win.auth.pwd.l configure -text "Enter passphrase for\ [string range $user_id(pgp,auth_cur_key_sel) 0 60]$dotdot" -font [resource infoFont] } return } proc pgp_create_signature {irand} { global recv_result global asympass global user_id global key_id global recv_authmessage global env putlogfile "Entered pgp_create_signature : irand = $irand" set local_authkey_file "[glob -nocomplain [resource sdrHome]]/$irand.pgp" set local_authsig_file "[glob -nocomplain [resource sdrHome]]/$irand.sig" set local_authtxt_file "[glob -nocomplain [resource sdrHome]]/$irand.txt" putlogfile "pgp_create_sig: local_authkey_file = $local_authkey_file" putlogfile "pgp_create_sig: local_authsig_file = $local_authsig_file" putlogfile "pgp_create_sig: local_authtxt_file = $local_authtxt_file" set pgpdir "[glob -nocomplain ~]/.pgp" putlogfile "pgp_create_sig: pgpdir = $pgpdir" if [info exists env(PGPPATH)] { set env(PGPPATH) $env(PGPPATH) putlogfile "pgp_create_sig: env fd - env(PGPPATH) = $env(PGPPATH)" } else { putlogfile "pgp_create_sig: no env fd" if { [file isdirectory $pgpdir ] == 0} { if { [ enter_pgp_path] == 0 } { return 0 } } else { set env(PGPPATH) $pgpdir } } putlogfile "pgp_create_sig: PGPPATH is $env(PGPPATH)" set tclcmd [ list exec pgp -sb -z $asympass +batchmode=on \ +verbose=0 -u ] set tclcmd [ concat $tclcmd 0x$key_id(pgp,auth_cur_key_sel) ] set tclcmd [ concat $tclcmd [ list $local_authtxt_file \ -o $local_authsig_file ] ] putlogfile "pgp_create_sig: about to execute tclcmd = $tclcmd" set result [catch $tclcmd output] putlogfile "pgp_create_sig: executed tclcmd = $tclcmd" putlogfile "pgp_create_sig: result= $result output= $output" # Either bad passphrase, we have not set-up the correct files properly # in 'generate_authentication_info, or PGP doesn't work properly... # May want to limit the error problem to a bad passphrase, only. This # can be achieved by tighter control over errors incurred in previous # functions. #if { $result == 1 } { putlogfile "pgp_create_sig: calling pgp_InterpretOutput $output pgpresult 1" pgp_InterpretOutput $output pgpresult 1 set pgpresult(msg) [pgp_ShortenOutput $pgpresult(msg) $pgpresult(summary) $pgpresult(keyid) $pgpresult(userid) $pgpresult(siglen) $pgpresult(date) $pgpresult(sigdate)] putlogfile "pgp_create_sig: pgpresult(msg) set to $pgpresult(msg)" if {$pgpresult(ok) == 0} { putlogfile "pgp_create_sig pgpresult(ok)=$pgpresult(ok)" set recv_result "0" return 0 } #} set mess [concat "The message is signed using keyid" 0x$key_id(pgp,auth_cur_key_sel)] set recv_authmessage $mess set tclcmd [ list exec pgp -kx +batchmode=on +verbose=0 ] set tclcmd [ concat $tclcmd 0x$key_id(pgp,auth_cur_key_sel) ] set tclcmd [ concat $tclcmd $local_authkey_file ] set result [catch $tclcmd output] if { $result == 1 } { #putlogfile "result= $result output= $output" pgp_InterpretOutput $output pgpresult 1 if {$pgpresult(ok) == 0} { #putlogfile "Something wrong here...cannot extract key for $user_id(pgp,auth_cur_key_sel) \n" set recv_result "0" return 0 } else { #putlogfile "$user_id(pgp,auth_cur_key_sel) key extracted...\n" } #putlogfile "Adding authentication to session announcement \n" set recv_result "1" return 1 } set recv_result "1" return 1 } # --------------------------------------------------------------------- # AUTH end # --------------------------------------------------------------------- proc pgp_create_encryption {irand} { global user_id global key_id global env global recv_encmessage global recv_result putlogfile "Entered pgp_create_encryption: irand = $irand" set local_sapenc_file "[glob -nocomplain [resource sdrHome]]/$irand.pgp" set local_enctxt_file "[glob -nocomplain [resource sdrHome]]/$irand.txt" set pgpdir "[glob -nocomplain ~]/.pgp" if [info exists env(PGPPATH)] { set env(PGPPATH) $env(PGPPATH) } else { if { [file isdirectory $pgpdir ] == 0} { if { [ enter_pgp_path] == 0 } { return 0 } } else { set env(PGPPATH) $pgpdir } } set configfile $env(PGPPATH)/config.txt putlogfile "pgp_create_encryption: env(PGPPATH) = $env(PGPPATH)" putlogfile "pgp_create_encryption: configfile = $env(PGPPATH)/config.txt" #putlogfile "env $env(PGPPATH)" if { [file exists $configfile] } { putlogfile "pgp_create_encryption: $configfile exists" set config [open $configfile r] set contents [read $config ] if { [regexp {.*EncryptToSelf = on.*} $contents {} contents] == 1} { #putlogfile " Config File is on" } else { set config [open $configfile a 0600] puts $config "EncryptToSelf = on" close $config } } else { putlogfile "pgp_create_encryption: $configfile doesnt exist" set config [open $configfile a 0600] puts $config "EncryptToSelf = on" close $config } set tclcmd [ list exec pgp -e +batchmode=on] set tclcmd [concat $tclcmd [ list $local_enctxt_file ]] set tclcmd [ concat $tclcmd 0x$key_id(pgp,enc_cur_key_sel) ] set tclcmd [concat $tclcmd [ list -o $local_sapenc_file ]] putlogfile "pgp_create_encryption: tclcmd = $tclcmd" set result [catch $tclcmd output] putlogfile "pgp_create_encryption: executed $tclcmd : result = $result : output = $output" #putlogfile "env $env(PGPPATH) $tclcmd output= $output" # if {$result == 1} { #return 0 #} set mess [concat "The message is encrypted for yourself using the most recent key on your secret key ring and user with keyid" 0x$key_id(pgp,enc_cur_key_sel)] #putlogfile " ENCRYPTION =$mess" set recv_encmessage $mess putlogfile "pgp_create_encryption: recv_encmessage = $recv_encmessage" #putlogfile "Adding PGP encryption to session announcement \n" set recv_result "1" putlogfile "pgp_create_encryption: recv_result = $recv_result" putlogfile "pgp_create_encryption: returning 1" return 1 } proc pgp_check_encryption {irand } { update global recv_enc_asym_keyid global recv_encstatus global recv_encmessage global env set resultkey 0 putlogfile "Entered pgp_check_encryption: irand = $irand" set local_sapenc_file "[glob -nocomplain [resource sdrHome]]/$irand.pgp" set local_enctxt_file "[glob -nocomplain [resource sdrHome]]/$irand.txt" set pgpdir "[glob -nocomplain ~]/.pgp" if [info exists env(PGPPATH)] { if {[string compare $env(PGPPATH) "none"] == 0 } { set recv_encstatus "failed" set recv_enc_asym_keyid "nonenone" set recv_encmessage "No Key Ring Path" set env(PGPPATH) "none" return 1 } else { set env(PGPPATH) $env(PGPPATH) } } else { if { [file isdirectory $pgpdir ] == 0} { if { [ enter_pgp_path] == 0 } { set recv_encstatus "failed" set recv_enc_asym_keyid "nonenone" set recv_encmessage "No Key Ring Path" set env(PGPPATH) "none" return 1 return 0 } } else { set env(PGPPATH) $pgpdir } } putlogfile "pgp_check_encryption: env(PGPPATH) = $env(PGPPATH)" set i 0 set j 0 if { [file exists $env(PGPPATH)/secring.enc] } { if [info exists env(SMARTLOC)] { putlogfile " SMART CARD Being Used" set resultkey 1 } else { if { [pgp_smart "SMARTCARD" " Place your smartcard" "OK" ] == 0 } { set resultkey 0 } else { while { $j == 0} { if { [enter_smart_pse_details] == 0 } { if { [file exists $env(PGPPATH)/secring.pgp] } { set tclcmd [ list exec pgp -kv $env(PGPPATH)/secring.pgp ] set resultkey [ catch $tclcmd keylist ] pgp_InterpretOutput $keylist pgpresult 1 if {$pgpresult(ok) == 1} { set i 1 set j 1 } else { timedmsgpopup "Secring view error" "Wrong smart card configration" 10000 set j 1 set resultkey 0 } } elseif { [file exists $env(PGPPATH)/secring.enc] } { timedmsgpopup "Secring view error" "You need SMART CARD Information" 10000 set j 0 catch { unset env(SMARTLOC)} set resultkey 0 } else { timedmsgpopup "Secring view error" "You need pgp ring files in $env(PGPPATH)" 10000 catch { unset env(SMARTLOC)} set j 1 set resultkey 0 } } else { set result [Misc_CheckSmart $env(SMARTPIN) $env(SMARTLOC)] while {$i == 0 } { if { $result == 1} { #putlogfile "The SMART pse and pin check OK" set env(USERPIN) $env(SMARTPIN) set tclcmd [ list exec secude pkcs7dec -p $env(SMARTLOC) -i $env(PGPPATH)/secring.enc -o $env(PGPPATH)/secring.pgp] set result [ catch $tclcmd output ] pkcs7_InterpretOutput $output pkcs7result if {$pkcs7result(ok) == 0} { timedmsgpopup "Secring view error" "Wrong smart card configration" 10000 catch {unset env(SMARTLOC)} catch {unset env(SMARTPIN)} set i 1 set j 0 } else { set i 1 set j 1 set tclcmd [ list exec pgp -kv $env(PGPPATH)/secring.pgp ] set resultkey [ catch $tclcmd keylist ] pgp_InterpretOutput $keylist pgpresult 1 if {$pgpresult(ok) == 1} { set i 1 set j 1 } else { set i 1 set j 0 set resultkey 0 timedmsgpopup "Secring view error" "Wrong smart card configration" 10000 } } } else { catch {unset env(SMARTLOC)} catch {unset env(SMARTPIN)} if {[enter_smart_pse_details ] == 0} { if { [file exists $env(PGPPATH)/secring.pgp] } { set tclcmd [ list exec pgp -kv $env(PGPPATH)/secring.pgp ] set resultkey [ catch $tclcmd keylist ] pgp_InterpretOutput $keylist pgpresult 1 if {$pgpresult(ok) == 1} { set i 1 set j 1 } else { set i 1 set j 0 timedmsgpopup "Secring view error" "Wrong smart card configration" 10000 set resultkey 0 catch {unset env(SMARTLOC)} catch {unset env(SMARTPIN)} } } elseif { [file exists $env(PGPPATH)/secring.enc] } { timedmsgpopup "Secring view error" "You need SMART CARD Information" 10000 set i 1 set j 0 set resultkey 0 } else { timedmsgpopup "Secring view error" "You need pgp ring files in $env(PGPPATH)" 10000 set resultkey 0 } } else { set result [Misc_CheckSmart $env(SMARTPIN) $env(SMARTLOC) ] } } } } } } } } else { if { [file exists $env(PGPPATH)/secring.pgp] } { set tclcmd [ list exec pgp -kv $env(PGPPATH)/secring.pgp ] set resultkey [ catch $tclcmd keylist ] pgp_InterpretOutput $keylist pgpresult 1 if {$pgpresult(ok) == 1} { set resultkey 1 } else { timedmsgpopup "Secring view error" "Wrong smar t card configration" 10000 return 0 } } else { set resultkey 0 } } if { $resultkey == 1} { set tclcmd [ list exec pgp +batchmode=on $local_sapenc_file -o $local_enctxt_file] #putlogfile "$tclcmd \n" set result [ catch $tclcmd output ] #putlogfile "$output" pgp_InterpretOutput $output pgpresult 1 #putlogfile "OK=$pgpresult(ok) summary: $pgpresult(summary)" if {$pgpresult(ok) == 1} { set recv_encstatus "success" regsub -all {\"} $pgpresult(msg) {} mess set recv_encmessage $mess set recv_encmessage [concat "\n Message Decryption: Success\n " "\n Key Information: \n Key Length: " $pgpresult(siglen) "\n Key Creation Date:" $pgpresult(date) "\n Key ID:" $pgpresult(keyid)] set recv_enc_asym_keyid $pgpresult(keyid) } else { # set result [pgpExecw [list $local_sapenc_file -o $local_enctxt_file] output] set test [regexp -nocase {user id:(.+)} $output {} userw] if {$test == 1} { set key [lindex $userw 0] set interactive 0 set result [pgpExec [list $local_sapenc_file \ -o $local_enctxt_file] output $key $irand $interactive] } else { set recv_encstatus "failed" set recv_enc_asym_keyid "nonenone" set pgpresult(msg) [pgp_ShortenOutput $pgpresult(msg) $pgpresult(summary) "none" "none" "none" "none" "none"] regsub -all {\"} $pgpresult(msg) {} mess set recv_encmessage $mess #timedmsgpopup "Decr: $pgpresult(msg)" "$recv_encstatus" 10000 return 1 } } # The error information must be conveyed to the user - more work # required....Need a mechanism to identify the session announcement to # the user. pgp_InterpretOutput $output pgpresult $key #putlogfile "OK=$pgpresult(ok) summary: $pgpresult(summary)" if {$pgpresult(ok) == 1} { set recv_enc_asym_keyid $pgpresult(keyid) set recv_encstatus "success" set recv_encmessage [concat ". \n Message Decryption: Success\n User:" $key ". \n key information:\n Key ID:" $pgpresult(keyid) ".\n Key Length: " $pgpresult(siglen) "Bits \n Key Creation Date:" $pgpresult(date) ] #set recv_encmessage [concat "Message were Successfully Decrepted for" $key ] } else { set result [pgpExec [list $local_sapenc_file \ -o $local_enctxt_file] output $key $irand 0] pgp_InterpretOutput $output pgpresult $key if {$pgpresult(ok) == 1} { #putlogfile "keyid:$pgpresult(keyid)" set recv_encmessage [concat ". \n Message Decryption: Success\n User:" $key ". \n key information:\n Key ID:" $pgpresult(keyid) ".\n Key Length: " $pgpresult(siglen) "Bits \n Key Creation Date:" $pgpresult(date) ] #set recv_encmessage [concat "Message were Successfully Decrepted for" $key ] set recv_encstatus "success" set recv_enc_asym_keyid $pgpresult(keyid) } else { set recv_encstatus "failed" set recv_enc_asym_keyid "nonenone" set recv_encmessage $pgpresult(msg) } } } else { set recv_encstatus "failed" set recv_enc_asym_keyid "nonenone" set recv_encmessage "Decryption failed" } #timedmsgpopup "Decryption= $pgpresult(msg)" "$recv_encstatus" 10000 putlogfile "pgp_check_encryption: recv_encstatus = $recv_encstatus" putlogfile "pgp_check_encryption: recv_enc_asym_keyid = $recv_enc_asym_keyid" putlogfile "pgp_check_encryption: recv_encmessage = $recv_encmessage" putlogfile "pgp_check_encryption: about to return 1" return 1 } # --------------------------------------------------------------------- # AUTH end # --------------------------------------------------------------------- proc pgp_InterpretOutput { in outvar key} { global env # This function is supposed to take the output given by the other # pgp exec procedures and writes different information to the # given array. It is probably best to put all the code that # change from PGP version to version in a single place. This is # based on 2.6.2 upvar $outvar pgpresult putlogfile "entered pgp_InterpretOutput" putlogfile " pgp_InterpretOutput: in = $in" putlogfile " pgp_InterpretOutput: outvar = $outvar" putlogfile " pgp_InterpretOutput: key = $key" set pgpdir "[glob -nocomplain ~]/.pgp" if [info exists env(PGPPATH)] { set env(PGPPATH) $env(PGPPATH) } else { if { [file isdirectory $pgpdir ] == 0} { if { [ enter_pgp_path] == 0 } { return 0 } } else { set env(PGPPATH) $pgpdir } } putlogfile " pgp_InterpretOutput: env(PGPPATH) = $env(PGPPATH)" if {[regexp {(.*)child process exited abnormally} $in {} in] == 1} { set in [string trim $in] } #set pgpresult(long) $in putlogfile " pgp_InterpretOutput: setting pgpresult(ok) to be 1" set pgpresult(ok) 1 if { [ regexp -nocase {key id ([0-9a-f]+)} $in {} pgpresult(keyid)] == 1} { putlogfile " pgp_InterpretOutput: keyid == $pgpresult(keyid)" } elseif { [ regexp -nocase {Key ID ([0-9a-f]+)} $in {} pgpresult(keyid)] == 1} { putlogfile " pgp_InterpretOutput: keyid == $pgpresult(keyid)" } else { set pgpresult(keyid) "nonenone" } if { [regexp {user ("[^"]*")} $in {} pgpresult(userid)] == 1} { putlogfile " pgp_InterpretOutput: USER = $pgpresult(userid) " } else { if { $key != 1 } { set pgpresult(userid) $key } else { set pgpresult(userid) "none" } } if { $pgpresult(userid) != "none" } { set tclcmdkey [ list exec pgp -kv +batchmode=on] set tclcmdkey [concat $tclcmdkey $pgpresult(userid)] putlogfile " pgp_InterpretOutput: $tclcmdkey" set resultkey [ catch $tclcmdkey output1 ] set keyinfo [split $output1 "\n"] set i 0 foreach line $keyinfo { if { [regexp {^(pub|sec) +([0-9]+)/([0-9A-F]+) +([0-9]+)/([0-9]+)/([0-9]+) +(.*)$} $line pgpresult(line) sigid pgpresult(siglen) pgpresult(keyid) year month day pgpresult(userid)] == 1} { set pgpresult(date) [concat $year $month $day] putlogfile " pgp_InterpretOutput: $pgpresult(date) $pgpresult(siglen) $pgpresult(keyid) $pgpresult(userid)" } incr i } } else { set pgpresult(date) "none" set pgpresult(siglen) "none" } set pgpresult(sigdate) "Unknown" if { [regexp {.*Signature made (.*) GMT.*} $in {} pgpresult(sigdate)] == 1 } { putlogfile " pgp_InterpretOutput: $pgpresult(sigdate)" } if [regexp {This.*do not have the secret key.*file.} $in \ pgpresult(msg)] { set pgpresult(summary) "SecretMissing" set pgpresult(ok) 0 } elseif [regexp {File is encrypted.*} $in pgpresult(msg)] { if [regexp {Pass phrase is good} $pgpresult(msg)] { set pgpresult(summary) "GoodPass Phrase" } else {set pgpresult(summary) "BadPass Phrase"} } elseif [regexp {Can't.*can't check signature integrity.*} $in \ pgpresult(msg)] { set pgpresult(summary) "PublicMissing" set pgpresult(ok) 0 } elseif [regexp {WARNING:Bad signature,.*match file contents.*} $in \ pgpresult(msg)] { set pgpresult(summary) "BadContent" set pgpresult(ok) 0 } elseif [regexp {.*Bad pass phrase.*} $in \ pgpresult(msg)] { set pgpresult(summary) "BadPassA" set pgpresult(ok) 0 } elseif [regexp {WARNING:Can't.*can't check signature integrity.*} $in \ pgpresult(msg)] { set pgpresult(summary) "PublicMissing" set pgpresult(ok) 0 } elseif [regexp {Key matching expected Key .* not found in .*} $in \ pgpresult(msg)] { set pgpresult(summary) "PublicMissing" set pgpresult(ok) 0 } elseif [regexp {Keyring view error.*} $in \ pgpresult(msg)] { set pgpresult(summary) "SecringMissing" set pgpresult(ok) 0 } elseif [regexp {Can't open key ring file .*} $in \ pgpresult(msg)] { set pgpresult(summary) "SecringMissing" set pgpresult(ok) 0 } elseif [regexp {0 matching keys .*} $in \ pgpresult(msg)] { set pgpresult(summary) "SecringMissing" set pgpresult(ok) 0 } elseif [regexp {Good signature.*} $in pgpresult(msg)] { if [regexp {WARNING:.*confidence} $pgpresult(msg)] { set pgpresult(summary) "GoodSignatureUntrusted" } else {set pgpresult(summary) "GoodSignatureTrusted"} } elseif [regexp {WARNING:.*doesn't match.*} $in \ pgpresult(msg)] { if [regexp {WARNING:.*confidence.*} $pgpresult(msg)] { set pgpresult(summary) "BadSignatureUntrusted" } else {set pgpresult(summary) "BadSignatureTrusted" } set pgpresult(ok) 0 } elseif [regexp {Error:.*is not a ciphertext, signature, or key file.* } \ $in pgpresult(msg)] { set pgpresult(summary) "PublicMissing" set pgpresult(msg) $in set pgpresult(ok) 0 } elseif [regexp {Error:.*Badly-formed or corrupted signature .* } \ $in pgpresult(msg)] { set pgpresult(summary) "BadCert" set pgpresult(msg) $in set pgpresult(ok) 0 } elseif [regexp {ERROR} $in \ pgpresult(msg)] { set pgpresult(summary) "UnknownError" set pgpresult(msg) $in set pgpresult(ok) 0 } elseif [regexp {Enter.*Pass phrase is good.*} $in \ pgpresult(msg)] { set pgpresult(summary) "GoodPass Phrase" set pgpresult(ok) 1 } else { set pgpresult(summary) "Other" set pgpresult(msg) $in } # DecryptExpect sometimes notifies the user that the # file is not encrypted. if [regexp {Note: File may not have been encrypted} $in] { set pgpresult(msg) \ "Note: File may not have been encrypted.\n\n$pgpresult(msg)" } # if $pgp(shortmsgs) { #set pgpresult(msg) [pgp_ShortenOutput $pgpresult(msg) \ #$pgpresult(summary)] #} } proc pgp_ShortenOutput { pgpresult summary idkey user siglen date sigdate} { putlogfile "entered pgp_ShortenOutput" switch $summary { SecretMissing {return "\n Cannot decrypt, missing secret key for \n User: $user \n Keyid: $idkey \n key Length: $siglen Bits \n Key Createdion Date: $date."} PublicMissing {return "\n Missing Public Key \n Key matching expected \n Key ID: $idkey \n not found in the Public Key ring "} GoodSignatureUntrusted {return "\n Good untrusted Signature \n From: $user \n Keyid: $idkey \n Signature Length: $siglen Bits \n Key Created date: $date \n Signature date: $sigdate."} GoodSignatureTrusted {return "\n Good trusted Signature \n From: $user \n Keyid: $idkey \n Signature Length: $siglen Bits \n Key Creation date: $date \n Signature date: $sigdate. "} BadSignatureTrusted {return "\n WARNING: Bad trusted signature doesnot match file content, \n From user: $user \n keyid: $idkey \n Signature Length: $siglen Bits \n Signature created date: $date \n Signature date: $pgpresult(sigdate)."} BadSignatureUntrusted {return "\n WARNING: Bad untrusted signature, does not match file content \n From: $user \n Keyid $idkey \n Signature Length: $siglen Bits \n Key Creation Date: $date \n Signature date: $pgpresult(sigdate)."} GoodPass {return " Good Pass $user with keyid $idkey and Signature Lenght $siglen created $date."} BadPass {return "\n Bad Password \n From: $user \n Keyid: $idkey\n Signature Length $siglen Bits \n Key Creation Date: $date."} BadPassA {return "\n Bad Password \n From: $user \n Keyid: $idkey\n Signature Length $siglen Bits \n Key Creation Date: $date."} BadCert {return " \n Bad Signature File ."} BadContent {return "\n Doesnot Match Content ."} UnknownError {return "PGP Error while processing message:\n$pgpresult"} SecringMissing {return "PGP Secretering is missing Please enter your smart card detail to decrypt secring"} Other {return $pgpresult} } } proc pgpExec { arglist outvar key irand interactive } { upvar $outvar output global env if {$interactive !=0 } { return [pgpExec_Interactive $arglist output $irand] } else { if {$key == {}} { return [pgpExec_Batch $arglist output $irand] } else { set p [pgp_GetPass $key] if {[string length $p] == 0} { return 0 } return [pgpExec_Batch $arglist output $p] } } } proc pgpExec_Interactive { arglist outvar irand } { upvar $outvar output set args [concat [list +armorlines=0 +keepbinary=off] $arglist] set shcmd "unset PGPPASSFD; pgp \"[join [Misc_Map x { regsub {([$"\`])} $x {\\1} x set dummy $x } $args] {" "}]\"; echo echo press Return...; read dummy" #putlogfile " $shcmd" set logfile "[glob -nocomplain [resource sdrHome]]/x$irand" set tclcmd {exec xterm -l -lf $logfile -title PGP -e sh -c $shcmd} #putlogfile "$tclcmd" set result [catch $tclcmd] if [catch {open $logfile r} log] { set output "" } else { set output [read $log] close $log } # clean up the output # regsub -all "\[\x0d\x07]" $output "" output #regsub "^.*\nEnter pass phrase:" $output "" output #regsub "\nPlaintext filename:.*" $output "" output #regsub "^.*Just a moment\\.\\.+" $output "" output #regsub "^.*Public key is required \[^\n]*\n" $output "" output #set output [string trim $output] return $result } proc Misc_Map { var expr list } { upvar $var elem set result "" foreach elem $list { lappend result [uplevel $expr] } return $result } proc pgpExecw { arglist outvar } { upvar $outvar output global env set p [pgp_GetPass ] if {[string length $p] == 0} { return 0 } return [pgpExec_Batch $arglist output $p] } proc pgp_GetPass { key } { global pgpPass global sspass global ppass set keyname [lindex $key 0] if [info exists sspass] { if {$sspass == 0} { if [info exists pgpPass($keyname)] { return $pgpPass($keyname) } set passtimeout 60 while 1 { if [catch {Misc_GetPass "Enter PGP password" "password for $key "} passw ] { return {} } elseif {[pgpExec_CheckPassword $passw $key]} { set pgpPass($keyname) $passw #after [expr $passtimeout * 60 * 1000] \ # [list pgp_ClearPassword $key] return $passw } } } else { set pgpPass($keyname) $ppass return $pgpPass($keyname) } } else { if [info exists pgpPass($keyname)] { return $pgpPass($keyname) } set passtimeout 60 while 1 { if [catch {Misc_GetPass "Enter PGP password" "password for $key "} passw] { return {} } elseif {[pgpExec_CheckPassword $passw $key]} { set pgpPass($keyname) $passw #after [expr $passtimeout * 60 * 1000] \ # [list pgp_ClearPassword $key] return $passw } } } } proc pgp_ClearPassword {{keyname {}}} { global pgpPass if {[string length $keyname] == 0} { catch {unset pgpPass} set pgpPass() {} } else { #putlogfile "$keyname" catch {unset pgpPass($keyname)} } } proc pgpExec_Batch { arglist outvar passw } { upvar $outvar output global env # pgp 4.0 command doesn't like the +keepbinary=off option set pgpdir "[glob -nocomplain ~]/.pgp" if [info exists env(PGPPATH)] { set env(PGPPATH) $env(PGPPATH) } else { if { [file isdirectory $pgpdir ] == 0} { if { [ enter_pgp_path] == 0 } { return 0 } } else { set env(PGPPATH) $pgpdir } } set tclcmd [concat \ [list exec pgp +armorlines=0 +batchmode=on +pager=cat] \ $arglist] #putlogfile "password= $passw" if {$passw == {}} { catch { unset env(PGPPASSFD) } } else { lappend tclcmd << $passw set env(PGPPASSFD) 0 } #putlogfile " $tclcmd " set result [catch $tclcmd output] #putlogfile "result $result " #putlogfile "output $output " regsub -all "\x07" $output "" output #putlogfile "$output" catch { unset env(PGPPASSFD) } return $result } proc certExec { arglist outvar irand} { upvar $outvar output global env return [certExec_Interactive $arglist output $irand] } proc certExec_Interactive { arglist outvar irand } { upvar $outvar output set args [concat [list +armorlines=0 +keepbinary=off] $arglist] set shcmd "unset PGPPASSFD; pgp \"[join [Misc_Map x { regsub {([$"\`])} $x {\\1} x set dummy $x } $args] {" "}]\"; echo echo press Return...; read dummy" #putlogfile " $shcmd" set logfile "[glob -nocomplain [resource sdrHome]]/x$irand" set tclcmd {exec xterm -l -lf $logfile -title PGP -e sh -c $shcmd} #putlogfile "$tclcmd" set result [catch $tclcmd] if [catch {open $logfile r} log] { set output "" } else { set output [read $log] #putlogfile "$output" close $log } return $result } proc toggle_pass {} { global spass global sspass if {$spass=="yes"} { set sspass 1 } else { set sspass 0 } } proc Misc_GetPass { title label } { global getpass ppass spass sspass catch {destroy $w} set w [toplevel .getpass -borderwidth 10] wm title .getpass $title checkbutton $w.b1 -text "Same Pass" -variable spass\ -highlightthickness 0 -justify l \ -relief flat -onvalue yes -offvalue no \ -command "toggle_pass" #tixAddBalloon $w.b1 Button [tt "Select \"Same PASS\" If you are using the same passphrase for all your secret Keys in the secrekey ring. "] pack $w.b1 -side top -anchor nw label $w.lab -text $label pack $w.lab -side top -anchor w #password $w.entry -width 30 -relief sunken -borderwidth 1 \ -variable ppass password $w.entry -width 30 -relief sunken -borderwidth 1 -variable ppass \ -background [option get . entryBackground Sdr] pack $w.entry -side top -anchor w bind $w.entry "set getpass(ok) 1" frame $w.but pack $w.but -side top -fill x -expand true button $w.but.ok -text OK -command {set getpass(ok) 1 } pack $w.but.ok -side left -fill x -expand true button $w.but.cancel -text Cancel -command { set getpass(ok) 0} pack $w.but.cancel -side left -fill x -expand true grab $w tkwait variable getpass(ok) grab release $w destroy $w if { $getpass(ok) == 1} { #putlogfile " PASSWORD from MIS_GetPass " return $ppass } else { return {} } } proc Misc_Gettext { title label } { global gettext global ptext catch {destroy $w} set w [toplevel .gettext -borderwidth 10] wm title .gettext $title label $w.lab -text $label pack $w.lab -side top -anchor w entry $w.entry -width 30 -relief sunken -borderwidth 1 \ -bg [option get . entryBackground Sdr] \ -highlightthickness 0 -textvariable gettext(result) pack $w.entry -side left frame $w.but pack $w.but -side top -fill x -expand true button $w.but.ok -text OK -command {set gettext(ok) 1 } button $w.but.cancel -text Cancel -command { set gettext(ok) 0} pack $w.but.ok -side left -fill x -expand true pack $w.but.cancel -side left -fill x -expand true foreach f [list $w.entry $w.but.ok $w.but.cancel] { bindtags $f [list .gettext [winfo class $f] $f all] } bind .gettext "focus $w.but.ok ; break" bind .gettext "focus $w.but.cancel ; break" bind .gettext break bind .gettext { set gettext(ok) 1} bind .gettext { set gettext(ok) 0} focus $w.entry grab $w tkwait variable gettext(ok) grab release $w destroy $w if { $gettext(ok) == 1} { #putlogfile "$gettext(result)" return $gettext(result) } else { return 0 } } proc certExec { arglist outvar irand} { upvar $outvar output global env return [certExec_Interactive $arglist output $irand] } proc certExec_Interactive { arglist outvar irand } { upvar $outvar output set args [concat [list +armorlines=0 +keepbinary=off] $arglist] set shcmd "unset PGPPASSFD; pgp \"[join [Misc_Map x { regsub {([$"\`])} $x {\\1} x set dummy $x } $args] {" "}]\"; echo echo press Return...; read dummy" #putlogfile " $shcmd" set logfile "[glob -nocomplain [resource sdrHome]]/x$irand" set tclcmd {exec xterm -l -lf $logfile -title PGP -e sh -c $shcmd} #putlogfile "$tclcmd" set result [catch $tclcmd] if [catch {open $logfile r} log] { set output "" } else { set output [read $log] close $log } return $result } proc pgpExec_CheckPassword { passw key } { set tmpfile "[glob -nocomplain [resource sdrHome]]/pwdin" set outfile "[glob -nocomplain [resource sdrHome]]/pwdout" set out [open $tmpfile w 0600] puts $out "salut" close $out pgpExec_Batch [list -as $tmpfile -o $outfile -u [lindex $key 0]] err $passw file delete $tmpfile # pgp thinks he knows better how to name files ! if {![file exists $outfile] && [file exists "$outfile.asc"]} { pgp_Rename "$outfile.asc" $outfile } if {![file exists $outfile]} { if {![regexp "PGP" $err]} { # Probably cannot find pgp to execute. putlogfile " can't find pgp" } else { if [regexp {(Error:[^\.]*)\.} $err x match] { putlogfile " some error " } } return 0 } else { file delete $outfile #putlogfile "CHECKPASS" return 1 } } proc pgp_Rename { old new } { file rename -force $old $new } proc pgp_AddCert { filename title label } { global getans env set pgpdir "[glob -nocomplain ~]/.pgp" if [info exists env(PGPPATH)] { set env(PGPPATH) $env(PGPPATH) } else { if { [file isdirectory $pgpdir ] == 0} { if { [ enter_pgp_path] == 0 } { return 0 } } else { set env(PGPPATH) $pgpdir } } catch {destroy $w} set w [toplevel .getans -borderwidth 10] wm title .getans $title label $w.lab -text $label pack $w.lab -side top -fill x -expand true frame $w.but pack $w.but -side top -fill x -expand true button $w.but.yes -text YES -command {set getans(yes) 1 } button $w.but.no -text NO -command { set getans(yes) 0} pack $w.but.yes -side left -fill x -expand true pack $w.but.no -side left -fill x -expand true foreach f [list $w.but.yes $w.but.no] { bindtags $f [list .getans [winfo class $f] $f all] } bind .getans "focus $w.but.yes ; break" bind .getans "focus $w.but.no ; break" bind .getans break bind .getans { set getans(yes) 1} bind .getans { set getans(yes) 0} grab $w tkwait variable getans(yes) grab release $w destroy $w if { $getans(yes) == 1} { set tclcmd [ list exec pgp -ka +batchmode=on $filename] #putlogfile "$tclcmd" set result [catch $tclcmd output] return 1 } else { return 0 } } proc pgp_smart { title label but} { global getsmartans env set pgpdir "[glob -nocomplain ~]/.pgp" if [info exists env(PGPPATH)] { set env(PGPPATH) $env(PGPPATH) } else { if { [file isdirectory $pgpdir ] == 0} { if { [ enter_pgp_path] == 0 } { return 0 } } else { set env(PGPPATH) $pgpdir } } catch {destroy $w} set w [toplevel .getsmartans -borderwidth 10] wm title .getsmartans $title label $w.lab -text $label pack $w.lab -side top -fill x -expand true frame $w.but pack $w.but -side top -fill x -expand true button $w.but.yes -text $but -command {set getsmartans(yes) 1 } button $w.but.no -text NO -command { set getsmartans(yes) 0} pack $w.but.yes -side left -fill x -expand true pack $w.but.no -side left -fill x -expand true foreach f [list $w.but.yes $w.but.no] { bindtags $f [list .getsmartans [winfo class $f] $f all] } bind .getsmartans "focus $w.but.yes ; break" bind .getsmartans "focus $w.but.no ; break" bind .getsmartans break bind .getsmartans { set getsmartans(yes) 1} bind .getsmartans { set getsmartans(yes) 0} grab $w tkwait variable getsmartans(yes) grab release $w destroy $w if { $getsmartans(yes) == 1} { return 1 } else { return 0 } } proc Help_asym {help} { global sdr set sdrversion 2.5 set label "Key Generation" set local_help_file "[glob -nocomplain [resource sdrHome]]/$help.txt" if [Help_Toplevel .pgphelp "Key Generation Help" pgpHelp] { Help1_Label .pgphelp.but label {left fill} -text $label Help1_AddBut .pgphelp.but setup "Make PGP Key" [list pgp_Setup] Help1_AddBut .pgphelp.but setup1 "Make X509 Key" [list x509_Setup] Help1_AddBut .pgphelp.but setup2 "Make Des Key" [list Des_Setup] set help " For Asymmetric encryption and authentication we use Pretty Good Privacy (PGP) and Public Key Cryptographic System (PKCS7) and for symetric encryption DES. Pretty Good Privacy (tm) (PGP), from Network Associates, is a high security cryptographic software application for MSDOS, Unix, VAX/VMS, and other computers. PGP allows people to exchange files or messages with privacy, authentication, and convenience. PGP is based on public key cryptography. PGP combines the convenience of the Rivest-Shamir-Adleman (RSA) public key cryptosystem with the speed of symmetric cryptography. It uses message digests for digital signatures, data compression before encryption, good ergonomic design, and sophisticated key management. PGP uses \"message digests\" to form signatures. A message digest is a 128-bit cryptographically strong one-way hash function of the message. It is somewhat analogous to a \"checksum\" or CRC error checking code, in that it compactly \"represents\" the message and is used to detect changes in the message. Unlike a CRC, however, it is computationally infeasible for an attacker to devise a substitute message that would produce an identical message digest. The message digest gets encrypted by the private key to form a signature. Documents are signed by prefixing them with signature certificates, which contain the key ID of the key that was used to sign it, a private-key-signed message digest of the document, and a timestamp of when the signature was made. The receiver to look up the sender's public key to check the signature uses the key ID. The receiver's software automatically looks up the sender's public key and user ID in the receiver's public key ring. The key ID of the public key used to encrypt them prefixes encrypted files. The receiver uses this key ID message prefix to look up the private key needed to decrypt the message. The receiver's software automatically looks up the necessary private decryption key in the receiver's private key ring. Public Key Cryptographic System (PKCS7): There are many security toolkits. Our implementation of SDR v1.5 uses Secude for generating X509 keys and encryption and authentication. The Secude development kit is a library that offers well-known and established symmetric and asymmetric cryptography for popular hardware and operating system platforms. The development kit consists of a set of functions which allows the incorporation of security in practically any application (e.g. client/server, e-mail, office applications) and documentation in Hypertext Markup Language (HTML) which describes in detail the C programming interface. There are also various commands collected in a security command shell to ensure an immediate deployment of security. Before you generate keys you need to get an e-mail system which has the capability of sending information securely; for example Exmh can send encrypted and authenticated text body part using PGP. Eudora can send PGP and S-MIME authenticated and encrypted messages. Next you need to establish a group membership, possibly with an e-mail list. Section 3.4.1 of \"USER GUIDE\" shows the step required to generate DES, X509 and PGP keys and use your chosen mail system to send it to the group members. Section 3.4.2 of \"USER GUIDE\" will show you how to store keys recieved via E-mail to be used by SDR v2.5. " Help1_Text .pgphelp $help } } proc Help1_AddBut {par but txt cmd {where {right padx 1}} } { # Create a Packed button. Return the button pathname set cmd2 [list button $par.$but -text $txt -command $cmd] if [catch $cmd2 t] { catch {puts stderr "Help1_AddBut (warning) $t"} eval $cmd2 {-font fixed} } pack append $par $par.$but $where return $par.$but } proc Help_Toplevel { path name {class Dialog} {dismiss yes}} { global exwin if [catch {wm state $path} state] { set t [Help1_Toplevel $path $name $class] if ![info exists exwin(toplevels)] { set exwin(toplevels) [option get . exwinPaths {}] } set ix [lsearch $exwin(toplevels) $t] if {$ix < 0} { lappend exwin(toplevels) $t } if {$dismiss == "yes"} { set f [Help1_Frame $t but Menubar {top fill}] Help1_AddBut $f quit "Dismiss" [list Help1_Dismiss $path] } return 1 } else { if {$state != "normal"} { catch { wm geometry $path $exwin(geometry,$path) #putlogfile "Help_Toplevel $path $exwin(geometry,$path)" } wm deiconify $path } else { catch {raise $path} } return 0 } } proc Help1_Label { frame {name label} {where {left fill}} args} { set cmd [list label $frame.$name ] if [catch [concat $cmd $args] t] { #putlogfile "Help1_Label (warning) $t" eval $cmd $args {-font fixed} } pack append $frame $frame.$name $where return $frame.$name } proc Help1_Frame {par child {class Sdr} {where {top expand fill}} args } { if {$par == "."} { set self .$child } else { set self $par.$child } eval {frame $self -class $class} $args pack append $par $self $where return $self } proc Help1_Dismiss { path {geo ok} } { global exwin case $geo { "ok" { set exwin(geometry,$path) [wm geometry $path] } "nosize" { set exwin(geometry,$path) [string trimleft [wm geometry $path] 0 123456789x] } default { catch {unset exwin(geometry,$path)} } } if [info exists exwin(geometry,$path)] { # Some window managers return geometry like # 80x24+-1152+10 regsub -all {\+-} $exwin(geometry,$path) + exwin(geometry,$path) } #Sdr_Focus wm withdraw $path update idletasks ;# Helps window dismiss } proc Sdr_Focus {} { global exwin focus $exwin(mtext) } proc Help1_Toplevel { path name {class Dialog} {x {}} {y {}} } { set self [toplevel $path -class $class] set usergeo [option get $path position Position] if {$usergeo != {}} { if [catch {wm geometry $self $usergeo} err] { putlogfile "Help_Toplevel $self $usergeo => $err" } } else { if {($x != {}) && ($y != {})} { putlogfile "Event position $self +$x+$y" wm geometry $self +$x+$y } } wm title $self $name wm group $self . return $self } proc Help1_Text {frame help} { # Create the text widget used to display messages set local_help_file "[glob -nocomplain [resource sdrHome]]/$help.txt" global exwin set side right set t [text $frame.lb -setgrid true -width 40 -height 15 \ -yscroll "$frame.sb set" -relief \ flat -wrap none \ -selectforeground [resource activeForeground] \ -highlightthickness 0 ] scrollbar $frame.sb -command "$frame.lb yview" \ -background [resource scrollbarForeground] \ -troughcolor [resource scrollbarBackground] \ -borderwidth 1 -relief flat \ -highlightthickness 0 pack $frame.lb -side left -fill both -expand true pack $frame.sb -side right -fill y $t insert insert $help # if [catch {open $local_help_file r} in] { # $t insert insert "Cannot find file pgp.txt to display" # $t configure -state disabled # } else { # $t insert insert [read $in] # } } proc pgp_Setup { } { global pgp env set pgpdir "[glob -nocomplain ~]/.pgp" if [info exists env(PGPPATH)] { set env(PGPPATH) $env(PGPPATH) } else { if { [file isdirectory $pgpdir ] == 0} { if { [ enter_pgp_path] == 0 } { return 0 } } else { set env(PGPPATH) $pgpdir } } set PGPPATH $env(PGPPATH) set pgp(pgppath) $env(PGPPATH) # make the key pair and self sign it # exec xterm -title "PGP Setup" -e sh -c { # cd ${PGPPATH} # rm -f pubring.bak # pgp -kg # rm -f pubring.bak # pgp +verbose=0 +force=on -ks "" -u "" # } >& /dev/console exec xterm -title "PGP Setup" -e sh -c { cd ${PGPPATH} rm -f pubring.bak pgp -kg rm -f pubring.bak pgp +verbose=0 +force=on -ks "" -u "" } #if {![file exists "$env(PGPPATH)/pubring.bak"]} { #return #} set pgp(secring) $pgp(pgppath)/secring.pgp set pgp(privatekeys) [pgpExec_KeyList "" $pgp(secring)] #putlogfile "$pgp(privatekeys)" # send the key to the keyservers set pgpfile [pgpExec_GetKeys [lindex [lindex $pgp(privatekeys) 0] 0] ] if [info exists env(MAILAGENT] { set mailagent $env(MAILAGENT) } else { set mailagent [Misc_Gettext "MAILAGENT" "Please enter mail agent"] } if { $mailagent != 0 } { set tclcmd [ list exec $mailagent ] set result [ catch $tclcmd output ] file delete $pgpfile } } proc pgpExec_KeyList { pattern keyring } { set pattern [string trimleft $pattern "<>|2"] pgpExec_Batch [list -kv $pattern $keyring] keylist {} # drop the revoked keys regsub -all "\n(pub|sec) \[^\n]+\\*\\*\\* KEY REVOKED \\*\\*\\*(\n\[\t ] \[^\n]+)+" $keylist "" keylist if { ![regexp {.*(pub|sec) +[0-9]+(/| +)([0-9A-F]+) +[0-9]+/ ?[0-9]+/ ?[ 0-9]+ +(.*)} $keylist]} { return {} } else { set keylist [split $keylist "\n"] set keys {} set key {} foreach line $keylist { if [regexp {^ *(pub|sec) +[0-9]+(/| +)([0-9A-F]+) +[0-9]+/ ?[0-9 ]+/[0-9]+ +(.*)$} $line {} {} {} keyid userid] { #set key [list "0x$keyid" [string trim $userid]] set key [list [string trim $userid]] lappend keys $key } } return $keys } } proc pgpExec_GetKeys { key } { global env set pgpfile "[glob -nocomplain [resource sdrHome]]/pgpkeyfile" set pgpdir "[glob -nocomplain ~]/.pgp" if [info exists env(PGPPATH)] { set env(PGPPATH) $env(PGPPATH) } else { if { [file isdirectory $pgpdir ] == 0} { if { [ enter_pgp_path] == 0 } { return 0 } } else { set env(PGPPATH) $pgpdir } } set tmpfile "[glob -nocomplain [resource sdrHome]]/tmpfile" set p [pgp_GetPass $key] if {[string length $p] == 0} { return 0 } set fileid [open $pgpfile w] puts $fileid [concat "password: " $p] close $fileid set tclcmd [ list exec pgp -akx +armorlines=0 +batchmode=on $key $tmpfile $env(PGPPATH)/secring.pgp] set result [ catch $tclcmd output ] if {![file exists $tmpfile] && [file exists "$tmpfile.asc"]} { pgp_Rename "$tmpfile.asc" $tmpfile } set tmpid [open $tmpfile r] set content [read $tmpid] close $tmpid file delete $tmpfile set fileid [open $pgpfile a] puts $fileid $content close $fileid set tclcmd [ list exec pgp -akx +armorlines=0 +batchmode=on $key $tmpfile $env(PGPPATH)/pubring.pgp] set result [ catch $tclcmd output ] if {![file exists $tmpfile] && [file exists "$tmpfile.asc"]} { pgp_Rename "$tmpfile.asc" $tmpfile } set tmpid [open $tmpfile r] set content [read $tmpid] close $tmpid file delete $tmpfile set fileid [open $pgpfile a] puts $fileid $content close $fileid return $pgpfile } proc Des_Setup { } { global env deskey set result [creat_des_key] #putlogfile "$result" if { $result == 1 } { set desfile "[glob -nocomplain [resource sdrHome]]/deskeyfile" set i 0 while { $i == 0 } { if {[string length $deskey(pass)]<8} { bell timedmsgpopup "Encryption keys must be at least 8 characters" "TRY again" 3000 Des_Setup } else { if {[string compare $deskey(pass) $deskey(pass1)] !=0} { timedmsgpopup "You have not entered the same key twice" "TRY again" 3000 Des_Setup } else { set i 1 } } } set fileid [open $desfile w] puts $fileid [concat "DES Encryption Key: " $deskey(pass)] close $fileid set fileid [open $desfile a] puts $fileid [concat "DES Encryption Group: " $deskey(name)] close $fileid if [info exists env(MAILAGENT] { set mailagent $env(MAILAGENT) } else { set mailagent [Misc_Gettext "MAILAGENT" "Please enter mail agent"] } set tclcmd [ list exec $mailagent ] set result [ catch $tclcmd output ] file delete $desfile } } proc creat_des_key {} { global env desinfo deskey global desname despass despass1 catch {destroy $w} set w [toplevel .desinfo -borderwidth 2] wm title .desinfo "Sdr: Des Information to send to group" frame $w.f -borderwidth 5 -relief groove pack $w.f -side top message $w.f.l -aspect 500 -text "Please enter name of encryption group and key" pack $w.f.l -side top frame $w.f.f0 pack $w.f.f0 -side top -fill x -expand true label $w.f.f0.l -text "Des Encryption group" pack $w.f.f0.l -side left -anchor e -fill x -expand true entry $w.f.f0.e -width 40 -relief sunken -borderwidth 1 \ -bg [option get . entryBackground Sdr] \ -highlightthickness 0 -textvariable desname pack $w.f.f0.e -side left frame $w.f.f1 pack $w.f.f1 -side top -fill x -expand true label $w.f.f1.l -text "Encryption Key at least 8 character" pack $w.f.f1.l -side left -anchor e -fill x -expand true #entry ..f.f1.e -width 40 -relief sunken -borderwidth 1 \ # -bg [option get . entryBackground Sdr] \ # -highlightthickness 0 password $w.f.f1.e -width 30 -relief sunken -borderwidth 1 \ -variable despass -background [option get . entryBackground Sdr] pack $w.f.f1.e -side left frame $w.f.f2 pack $w.f.f2 -side top -fill x -expand true label $w.f.f2.l -text "Encryption Key (again)" pack $w.f.f2.l -side left -anchor e -fill x -expand true password $w.f.f2.e -width 30 -relief sunken -borderwidth 1 \ -variable despass1 -background [option get . entryBackground Sdr] pack $w.f.f2.e -side left frame $w.f.f3 pack $w.f.f3 -side top -fill x -expand true button $w.f.f3.ok -text OK -command {set desinfo(ok) 1 } pack $w.f.f3.ok -side left -fill x -expand true button $w.f.f3.cancel -text Cancel \ -command {set desinfo(ok) 0 } pack $w.f.f3.cancel -side left -fill x -expand true grab $w tkwait variable desinfo(ok) #grab release $w destroy .desinfo if { $desinfo(ok) == 1} { set deskey(name) $desname set deskey(pass) $despass set deskey(pass1) $despass1 destroy .desinfo return 1 } else { destroy .desinfo return 0 } } proc enter_pgp_path {} { global env pgpinfo yourkey yourpin catch {destroy $w} set w [toplevel .pgpinfo -borderwidth 2] wm title .pgpinfo "Sdr: PGP Configure Information" frame $w.f -borderwidth 5 -relief groove pack $w.f -side top message $w.f.l -aspect 500 -text "Please configure sdr with your PGP PATH " pack $w.f.l -side top frame $w.f.f0 pack $w.f.f0 -side top -fill x -expand true label $w.f.f0.l -text "PGP Key Ring Location" pack $w.f.f0.l -side left -anchor e -fill x -expand true entry $w.f.f0.e -width 30 -relief sunken -borderwidth 1 \ -bg [option get . entryBackground Sdr] \ -highlightthickness 0 -textvariable yourkey pack $w.f.f0.e -side left bind $w.f.f0.e "set pgpinfo(ok) 1" frame $w.f.f3 pack $w.f.f3 -side top -fill x -expand true button $w.f.f3.ok -text OK -command {set pgpinfo(ok) 1 } pack $w.f.f3.ok -side left -fill x -expand true button $w.f.f3.cancel -text Cancel \ -command {set pgpinfo(ok) 0 } pack $w.f.f3.cancel -side left -fill x -expand true grab $w tkwait variable pgpinfo(ok) grab release $w destroy .pgpinfo if { $pgpinfo(ok) == 1} { set env(PGPPATH) $yourkey return 1 } else { set env(PGPPATH) "none" return 0 } } proc show_pkcs7_keys {win} { $win.auth.pwd.e configure -state normal pkcs7_get_key_list $win } proc pkcs7_get_key_list { win } { global no_of_keys global user_id global key_id global env yourpse # Extract the owner of the pse and display it if [info exists env(PSELOC)] { set yourpse $env(PSELOC) set result 1 } else { set i 0 if { [enter_pse_details ] == 0} { return 0 } else { set result [Misc_CheckPse $env(PSEPIN) $env(PSELOC)] while {$i == 0 } { if { $result == 1} { #putlogfile "The pse and pinn check OK" set i 1 } else { catch {unset env(PSELOC)} catch {unset env(PSEPIN)} if {[enter_pse_details ] == 0} { return 0 } else { set result [Misc_CheckPse $env(PSEPIN) $env(PSELOC)] } } } } } set ownerl [Get_ownerlist ] if {$result == 0} { #putlogfile "Cannot open pse-file \n" } else { set ownerl [split $ownerl "<"] set i 0 foreach line $ownerl { #set result [regexp { Owner: (.+)} $line {} userid ] ##putlogfile "result = $result" if [regexp {Owner: (.+)} \ $line {} userid ] { set user_id(x509,$i) $userid set key_id(x509,$i) $line set key_id(x509,auth_cur_key_sel) "" if { [string length $userid] > 26 } { set dotdot "..." } else { set dotdot "" } $win.auth.keys.lb insert [expr $i+1].0 \ [string range $userid 0 26]$dotdot $win.auth.keys.lb insert end " \n" $win.auth.keys.lb tag add line$i [expr $i+1].0 \ [expr $i+1].end $win.auth.keys.lb tag configure line$i -background\ [option get . background Sdr] # Set-up bind on key selection $win.auth.keys.lb tag bind line$i <1>\ [format { global no_of_keys for {set i 0} {$i < $no_of_keys} {incr i} { %s.auth.keys.lb tag configure line$i\ -background [option get . background Sdr] } %s.auth.keys.lb tag configure line%s -background\ [option get . activeBackground Sdr] %s.auth.keys.lb configure -state disabled set user_id(x509,auth_cur_key_sel) $user_id(x509,%s) set key_id(x509,auth_cur_key_sel) $key_id(x509,%s) if { [string length $user_id(x509,auth_cur_key_sel)] > 18} { set dotdot "..." } else { set dotdot "" } %s.auth.pwd.l configure -text "No passphrase\ required for [string range $user_id(x509,auth_cur_key_sel) 0 18]$dotdot" \ -font [resource infoFont] } $win $win $i $win $i $i $win] incr i } } set no_of_keys $i if {$key_id(x509,auth_cur_key_sel) == ""} { set user_id(x509,auth_cur_key_sel) $user_id(x509,0) set key_id(x509,auth_cur_key_sel) $key_id(x509,0) } # Need to highlight previously used key in list or, if a new # session is being created, the first key in the list for {set i 0} {$i < $no_of_keys} {incr i} { if {$key_id(x509,auth_cur_key_sel)==$key_id(x509,$i)} { $win.auth.keys.lb tag configure line$i -background\ [option get . activeBackground Sdr] set user_id(x509,auth_cur_key_sel) $user_id(x509,$i) } } # Restrict how much we display of the user id of each key if { [string length $user_id(x509,auth_cur_key_sel)] > 18} { set dotdot "..." } else { set dotdot "" } $win.auth.pwd.l configure -text "No passphrase required for\ [string range $user_id(x509,auth_cur_key_sel) 0 18]$dotdot" -font [resource infoFont] } return } proc pkcs7_create_signature {irand} { global asympass global recv_result global cert global user_id global key_id global recv_authmessage global yourpse env set local_x509key_file "[glob -nocomplain [resource sdrHome]]/$irand.cert" set local_x509sig_file "[glob -nocomplain [resource sdrHome]]/$irand.sig" set local_x509sigcmp_file "[glob -nocomplain [resource sdrHome]]/$irand.sigcmp" set local_x509txt_file "[glob -nocomplain [resource sdrHome]]/$irand.txt" set local_x509bdy_file "[glob -nocomplain [resource sdrHome]]/$irand.btxt" if [info exists env(PSELOC)] { set yourpse $env(PSELOC) } else { set i 0 if { [enter_pse_details ] == 0} { set recv_result "0" return 0 } else { set result [Misc_CheckPse $env(PSEPIN) $env(PSELOC)] while {$i == 0 } { if { $result == 1} { #putlogfile "The pse and pinn check OK" set i 1 } else { catch {unset env(PSELOC)} catch {unset env(PSEPIN)} if {[enter_pse_details ] == 0} { set recv_result "0" return 0 } else { set result [Misc_CheckPse $env(PSEPIN) $env(PSELOC)] } } } } } set newpse [Get_Owner_PSE $user_id(x509,auth_cur_key_sel)] set tclcmd [ list exec secude pkcs7enc SIGNED-DATA -p $newpse -C $cert -i $local_x509txt_file -o $local_x509sigcmp_file -E $local_x509bdy_file ] ##putlogfile "$tclcmd \n" set result [catch $tclcmd output] set tclcmd [ list exec secude sec_zip $local_x509sigcmp_file $local_x509sig_file ] ##putlogfile "$tclcmd \n" set result [catch $tclcmd output] if { $result == 1 } { ##putlogfile " $output\n" ##putlogfile "result = $result " } #set tclcmd [ list exec secude psemaint -p $newpse export Cert $local_x509key_file ] ##putlogfile "$tclcmd \n" set result [catch $tclcmd output] #if {$result == 0} { # #putlogfile "Something wrong here...cannot extract key for $user_id(x509,\auth_cur_key_sel) \n" # return 0 #} else { # #putlogfile "$user_id(x509,auth_cur_key_sel) key extracted...\n" #} set tclcmd [ list exec secude psemaint -p $newpse own] set result [ catch $tclcmd ownerlist ] set ownerlist [regexp -nocase {PSE Owner: (.+)} $ownerlist {} ownerl] set mess "The Message were Successfully Signed Using" set recv_authmessage [ concat $mess $ownerl] #putlogfile "Adding authentication to session announcement \n" set recv_result "1" return 1 } proc pkcs7_cleanup {irand} { file delete "[glob -nocomplain [resource sdrHome]]/$irand.txt" file delete "[glob -nocomplain [resource sdrHome]]/$irand.btxt" file delete "[glob -nocomplain [resource sdrHome]]/$irand.sig" file delete "[glob -nocomplain [resource sdrHome]]/$irand.desig" file delete "[glob -nocomplain [resource sdrHome]]/$irand.cert" file delete "[glob -nocomplain [resource sdrHome]]/$irand.sigcmp" file delete "[glob -nocomplain [resource sdrHome]]/$irand.info" } proc enc_pkcs7_cleanup {irand} { file delete "[glob -nocomplain [resource sdrHome]]/$irand.txt" file delete "[glob -nocomplain [resource sdrHome]]/$irand.sym" file delete "[glob -nocomplain [resource sdrHome]]/$irand.cert" } proc pkcs7_check_authentication {irand} { global recv_result global env global recv_asym_keyid global recv_authstatus global recv_authmessage global yourpse set recv_asym_keyid "none" set local_x509txt_file "[glob -nocomplain [resource sdrHome]]/$irand.txt" set local_x509sig_file "[glob -nocomplain [resource sdrHome]]/$irand.sig" set local_x509desig_file "[glob -nocomplain [resource sdrHome]]/$irand.desig" set local_info_file "[glob -nocomplain [resource sdrHome]]/$irand.info" set local_key_file "[glob -nocomplain [resource sdrHome]]/$irand.cert" set i 0 if [info exists env(PSELOC)] { set yourpse $env(PSELOC) } else { set i 0 if { [enter_pse_details ] == 0} { set recv_result "0" return 0 } else { set result [Misc_CheckPse $env(PSEPIN) $env(PSELOC)] while {$i == 0 } { if { $result == 1} { #putlogfile "The pse and pinn check OK" set i 1 } else { catch {unset env(PSELOC)} catch {unset env(PSEPIN)} if {[enter_pse_details ] == 0} { set recv_result "0" return 0 } else { set result [Misc_CheckPse $env(PSEPIN) $env(PSELOC)] } } } } } set tclcmd [ list exec secude sec_zip -d $local_x509sig_file $local_x509desig_file ] ##putlogfile "$tclcmd" set result [ catch $tclcmd output ] if { $result == 1 } { ##putlogfile "OUTPUTZIP $output" } set newpse [Get_PSE $local_x509desig_file $irand] set tclcmd [ list exec secude pkcs7dec -p $newpse -i $local_x509desig_file -E $local_x509txt_file ] #putlogfile "$tclcmd" set result [ catch $tclcmd output ] if { $result == 1 } { #putlogfile "OUTPUT $output" } pkcs7_InterpretOutput $output pkcs7result set pkcs7result(msg) [pkcs7_ShortenOutput $pkcs7result(msg) $pkcs7result(summary)] ##putlogfile "MSGshort = $pkcs7result(msg) " #putlogfile "OKshort=$pkcs7result(ok) summary: $pkcs7result(summary)" set tclcmd [ list exec secude asn1show $local_x509desig_file] set result [ catch $tclcmd certinfo] set infofile [open $local_info_file w 0600] puts $infofile $certinfo close $infofile set certinfofile [get_cert_info $local_info_file] file delete $local_info_file if {$pkcs7result(ok) == 1} { set recv_authstatus "trustworthy" #regsub -all {\<} $pkcs7result(keyid) {} test1 #regsub -all {\>} $test1 {} test2 #regsub -all {\\} $test2 {} test3 #regsub -all {\\} $test2 {} test3 set dmess "\. \nPSE location: $newpse \n Signer Information \n" set recv_authmessage [concat " \.\nSuccess\n" $pkcs7result(msg) $dmess $pkcs7result(keyid) $certinfofile] set recv_asym_keyid $pkcs7result(keyid) #timedmsgpopup " $pkcs7result(msg) from $pkcs7result(keyid) " " $recv_authstatus" 10000 } else { set recv_authstatus "failed" set dmess "\. \nPSE location: $newpse \n Signer Information \n" set recv_authmessage [concat "\.\nFailed\n" $pkcs7result(msg) $dmess $pkcs7result(keyid) $certinfofile] set recv_asym_keyid $pkcs7result(keyid) #timedmsgpopup "$pkcs7result(msg) $pkcs7result(keyid) \n" "$recv_authstatus" 10000 } Addx509-cert-alias $local_x509desig_file $pkcs7result(dn) #timedmsgpopup "$pkcs7result(msg)" "$recv_symstatus" 10000 set recv_result "1" return 1 } proc pkcs7_InterpretOutput { in outvar } { upvar $outvar pkcs7result set pkcs7result(ok) 1 if {[regexp {Certificate of owner (<[^<]*>).*} $in {} user] == 1 } { set pkcs7result(keyid) $user set pkcs7result(dn) $user } elseif {[regexp {Certificate of .* (<[^<]*>).*} $in {} use] == 1 } { set pkcs7result(keyid) $use } else { set pkcs7result(keyid) "none" } if {[regexp {.*issued by (<[^<]*>).*} $in {} iss] == 1 } { set pkcs7result(issued) $iss } else { set pkcs7result(issued) "none" } if {[regexp {.*serial number: (.*)\(.*} $in {} serial] == 1 } { set pkcs7result(serialno) $serial } else { set pkcs7result(serialno) "none" } ##putlogfile "key-id = $pkcs7result(keyid)" if [regexp {.*failed.*} $in pkcs7result(msg)] { if [regexp {You are not on the recipients.*} $in pkcs7result(msg)] { set pkcs7result(summary) "SecMissing" set pkcs7result(ok) 0 } elseif [regexp {The verification of the text signature failed.*} $in pkcs7result(msg)] { set pkcs7result(summary) "BadContent" set pkcs7result(ok) 0 } else { set pkcs7result(summary) "CertMissing" set pkcs7result(ok) 0 } } elseif [regexp {.* n o t validated .*} $in \ pkcs7result(msg)] { set pkcs7result(summary) "PublicMissing" set pkcs7result(ok) 0 } elseif [regexp {Can't.*can't check signature integrity.*} $in \ pkcs7result(msg)] { set pkcs7result(summary) "PublicMissing" set pkcs7result(ok) 0 } elseif [regexp {Can't find recipients .*} $in \ pkcs7result(msg)] { set pkcs7result(summary) "PublicMissing" set pkcs7result(ok) 0 } elseif [regexp {Can't open PSE.*} $in \ pkcs7result(msg)] { set pkcs7result(summary) "MissingPSE" set pkcs7result(ok) 0 } elseif [regexp {The PSE is not .*} $in \ pkcs7result(msg)] { set pkcs7result(summary) "MissingPSE" set pkcs7result(ok) 0 } elseif [regexp {Invalid PIN .*} $in \ pkcs7result(msg)] { set pkcs7result(summary) "WrongPIN" set pkcs7result(ok) 0 } elseif [regexp {.* segmentation violation .*} $in \ pkcs7result(msg)] { set pkcs7result(summary) "SegViolation" set pkcs7result(ok) 0 } elseif [regexp {.* segmentation violation} $in \ pkcs7result(msg)] { set pkcs7result(summary) "SegViolation" set pkcs7result(ok) 0 } elseif [regexp {Object is not in to.*} $in \ pkcs7result(msg)] { set pkcs7result(summary) "Missing Alias File" set pkcs7result(ok) 0 } elseif [regexp {ERROR} $in pkcs7result(msg)] { set pkcs7result(summary) "UnknownError" set pkcs7result(msg) $in set pkcs7result(ok) 0 } elseif [regexp {which was trusted and found in PKList} $in pkcs7result(msg)] { set pkcs7result(summary) "GoodSig" set pkcs7result(ok) 1 } else { set pkcs7result(summary) "Other" set pkcs7result(msg) $in } } proc pkcs7_ShortenOutput { pkcs7result summary } { switch $summary { CertMissing {return "Missing Certificate Path "} SecMissing {return "Missing Secretkey for Decryption "} MissingPSE {return "Missing PSE "} SegViolation {return "segmentation violation "} MissingAlias {return "Missing Alias File "} WrongPIN {return "Wrong PIN "} GoodSig {return " Good Trusted Signature\n "} BadContent {return " The verification of the text signature failed"} UnknownError {return " Error while processing message:$pkcs7result"} Other {return $pkcs7result} } } proc Misc_GetX509Pass { title label } { global getpassx509 global x509pass catch {destroy $w} set w [toplevel .getpassx509 -borderwidth 10] wm title .getpassx509 $title label $w.lab -text $label pack $w.lab -side top -anchor w password $w.entry -width 30 -relief sunken -borderwidth 1 \ -variable x509pass pack $w.entry -side top -anchor w frame $w.but pack $w.but -side top -anchor w button $w.but.ok -text OK -command {set getpassx509(ok) 1 }\ -underline 0 button $w.but.cancel -text Cancel -command { set getpassx509(ok) 0} \ -underline 0 pack $w.but.ok -side left -fill x -expand true pack $w.but.cancel -side right -fill x -expand true grab $w tkwait variable getpassx509(ok) grab release $w destroy $w if { $getpassx509(ok) == 1} { set passpkcs "[glob -nocomplain [$x509pass]" return $passpkcs } else { return {} } } proc Misc_GetPseL { title label } { global getpinl global ppinl catch {destroy $w} set w [toplevel .getpinl -borderwidth 10] wm title .getpinl $title label $w.lab -text $label pack $w.lab -side top -anchor w entry $w.entry -textvariable getpinl(result) pack $w.entry -side top -anchor w frame $w.but pack $w.but -side top -anchor w button $w.but.ok -text OK -command {set getpinl(ok) 1 }\ -underline 0 button $w.but.cancel -text Cancel -command { set getpinl(ok) 0} \ -underline 0 pack $w.but.ok -side left -fill x -expand true pack $w.but.cancel -side right -fill x -expand true foreach f [list $w.entry $w.but.ok $w.but.cancel] { bindtags $f [list .getpinl [winfo class $f] $f all] } bind .getpinl "focus $w.but.ok ; break" bind .getpinl "focus $w.but.cancel ; break" bind .getpinl break bind .getpinl { set getpinl(ok) 1} bind .getpinl { set getpinl(ok) 0} focus $w.entry grab $w tkwait variable getpinl(ok) grab release $w destroy $w if { $getpinl(ok) == 1} { ##putlogfile "$getpinl(result)" return $getpinl(result) } else { return {} } } proc Misc_CheckPse {yourpin yourpse} { global env set tmpfile "[glob -nocomplain [resource sdrHome]]/pwdin" set outfile "[glob -nocomplain [resource sdrHome]]/pwdout" set out [open $tmpfile w 0600] puts $out "salut" close $out set env(USERPIN) $yourpin set tclcmd [ list exec secude pkcs7enc SIGNED-DATA -p $yourpse -i $tmpfile -o $outfile] ##putlogfile "$tclcmd" set result [ catch $tclcmd output ] if { $result == 1 } { #putlogfile "$output" } file delete $tmpfile file delete $outfile pkcs7_InterpretOutput $output pkcs7result if {$pkcs7result(ok) == 0} { ##putlogfile " checkresult = $pkcs7result(ok)" ##putlogfile "$pkcs7result(summary)" return 0 } else { ##putlogfile "$pkcs7result(summary)" return 1 } } proc Misc_CheckSmart {smartpin smartpse} { global env set tmpfile "[glob -nocomplain [resource sdrHome]]/pwdin" set outfile "[glob -nocomplain [resource sdrHome]]/pwdout" set out [open $tmpfile w 0600] puts $out "salut" close $out set env(USERPIN) $smartpin set tclcmd [ list exec secude pkcs7enc SIGNED-DATA -p $smartpse -i $tmpfile -o $outfile] ##putlogfile "$tclcmd" set result [ catch $tclcmd output ] if { $result == 1 } { #putlogfile "$output" } file delete $tmpfile file delete $outfile pkcs7_InterpretOutput $output pkcs7result if {$pkcs7result(ok) == 0} { ##putlogfile " checkresult = $pkcs7result(ok)" ##putlogfile "$pkcs7result(summary)" return 0 } else { ##putlogfile "$pkcs7result(summary)" return 1 } } proc enc_show_x509_keys {win aid} { enc_x509_get_key_list $win $aid } proc enc_x509_get_key_list {win aid} { global no_of_keys global user_id global key_id global sig_id global ldata global env ##putlogfile "enc_x509_get_key_list" set alfile "[glob -nocomplain [resource sdrHome]]/pks-als.txt" if { [file exists $alfile] } { #putlogfile "file exists" } else { set certfile "[glob -nocomplain [resource sdrHome]]/owncert" # Extract the owner of the pse and display it if [info exists env(PSELOC)] { set yourpse $env(PSELOC) } else { set i 0 if { [enter_pse_details ] == 0} { return 0 } else { set result [Misc_CheckPse $env(PSEPIN) $env(PSELOC)] while {$i == 0 } { if { $result == 1} { #putlogfile "The pse and pinn check OK" set yourpse $env(PSELOC) set i 1 } else { catch {unset env(PSELOC)} catch {unset env(PSEPIN)} if {[enter_pse_details ] == 0} { return 0 } else { set result [Misc_CheckPse $env(PSEPIN) $env(PSELOC) ] set yourpse $env(PSELOC) } } } } } set test 100 set userpin $env(USERPIN) unset env(USERPIN) set tclcmd [ list exec secude psemaint -p $env(PSELOC).$test ] set result [ catch $tclcmd noofpse] set env(USERPIN) $userpin if { [regexp {Selected PSE not in MPSEFile\, valid only ([0-9]+) to ([0-9]+)} $noofpse {} start end] == 1 } { incr end for {set i $start} {$i < $end } {incr i } { set tclcmd [ list exec secude psemaint -p $env(PSELOC).$i own] set result [ catch $tclcmd ownerlist ] set ownerlist [regexp -nocase {PSE Owner: (.+)} $ownerlist {} owndn($i)] set tclcmd [ list exec secude psemaint -p $env(PSELOC).$i export Cert $certfile ] set result [ catch $tclcmd output ] set tclcmd [list exec secude psemaint -p $env(PSELOC).$i addpk $certfile] set tclcmd [list exec secude psemaint -p $env(PSELOC).$start addpk $certfile] set result [ catch $tclcmd output ] file delete $certfile #set owndn [concat "<" $owndn ">"] set out [open $alfile a 0600] puts $out $owndn($i) close $out } } else { set tclcmd [ list exec secude psemaint -p $env(PSELOC) own] set result [ catch $tclcmd ownerlist ] set ownerlist [regexp -nocase {PSE Owner: (.+)} $ownerlist {} owndn(1)] set tclcmd [ list exec secude psemaint -p $env(PSELOC) export Cert $certfile] set result [ catch $tclcmd output ] set tclcmd [list exec secude psemaint -p $env(PSELOC) addpk $certfile] set result [ catch $tclcmd output ] file delete $certfile #set owndn [concat "<" $owndn ">"] set out [open $alfile a 0600] puts $out $owndn(1) close $out } } set out [open $alfile r] set i 0 $win.enc.keys.lb delete 0 end while { [gets $out line ] >= 0 } { set user_id(x509,$i) $line set key_id(x509,$i) $line set key_id(x509,enc_cur_key_sel) $key_id(x509,0) if { [string length $line] > 26 } { set dotdot "..." } else { set dotdot "" } set keyn [string range $line 0 26]$dotdot #$win.enc.keys.lb delete $i end $win.enc.keys.lb insert $i "$keyn" ##putlogfile "i= $i keyn=$keyn" incr i } close $out set no_of_keys $i bind $win.enc.keys.lb <1> "%W selection clear 0 end;\ %W selection set \[%W nearest %y\];\ [ format { global no_of_keys global user_id key_id set selkey [%s.enc.keys.lb curselection] if {$selkey==""} { errorpopup "No Key Selected" "You must select a key for encryption" log "user selected no key" return 0 } %s.enc.keys.lb get [lindex $selkey 0] #%s.enc.keys.lb configure -state normal set x509key [lindex $selkey 0] set user_id(x509,enc_cur_key_sel) $user_id(x509,$x509key) set key_id(x509,enc_cur_key_sel) $key_id(x509,$x509key) if { [string length $user_id(x509,enc_cur_key_sel)] > 18} { set dotdot "..." } else { set dotdot "" } } $win $win $win $win] " if {([string compare $aid "new"]!=0)&&($ldata($aid,enc_asym_keyid)!="")} { for {set i 0} {$i < $no_of_keys} {incr i} { if {[string compare $ldata($aid,enc_asym_keyid) $key_id(x509,$i)] == 0} { $win.enc.keys.lb selection set $i set user_id(x509,enc_cur_key_sel) $user_id(x509,$i) break } } } return } proc pkcs7_create_encryption {irand} { global user_id global key_id global env global yourpse global recv_result global recv_encmessage set local_sapenc_file "[glob -nocomplain [resource sdrHome]]/$irand.sym" set local_enctxt_file "[glob -nocomplain [resource sdrHome]]/$irand.txt" if [info exists env(PSELOC)] { set yourpse $env(PSELOC) } else { set i 0 if { [enter_pse_details ] == 0} { set recv_result "0" return 0 } else { set result [Misc_CheckPse $env(PSEPIN) $env(PSELOC)] while {$i == 0 } { if { $result == 1} { #putlogfile "The pse and pinn check OK" set i 1 } else { catch {unset env(PSELOC)} catch {unset env(PSEPIN)} if {[enter_pse_details ] == 0} { set recv_result "0" return 0 } else { set result [Misc_CheckPse $env(PSEPIN) $env(PSELOC) ] } } } } } set tclcmd [ list exec secude psemaint -p $yourpse own] set result [ catch $tclcmd ownerlist ] set ownerlist [regexp -nocase {PSE Owner: (.+)} $ownerlist {} ownerl] set tclcmd [ list exec secude pkcs7enc ENVELOPED-DATA] set tclcmd [concat $tclcmd -p $yourpse] set tclcmd [concat $tclcmd -r \"$key_id(x509,enc_cur_key_sel)\"] set tclcmd [concat $tclcmd -r \"$ownerl\"] set tclcmd [concat $tclcmd -i $local_enctxt_file -o $local_sapenc_file] #putlogfile "$tclcmd" set result [catch $tclcmd output] if { $result == 1 } { #putlogfile "$output" } set mess [concat "The message was encrypted for both yourself, using your PSE public key, and user " $key_id(x509,enc_cur_key_sel)] set recv_encmessage $mess ##putlogfile "Adding x509 encryption to session announcement \n" set recv_result "1" return 1 } proc pkcs7_check_encryption {irand} { global recv_enc_asym_keyid global recv_encstatus global recv_encmessage global recv_result global env global yourpse set local_sapenc_file "[glob -nocomplain [resource sdrHome]]/$irand.sym" set local_enctxt_file "[glob -nocomplain [resource sdrHome]]/$irand.txt" set local_cert_file "[glob -nocomplain [resource sdrHome]]/$irand.cert" if [info exists env(PSELOC)] { set yourpse $env(PSELOC) } else { set i 0 if { [enter_pse_details ] == 0} { set recv_result "0" return 0 } else { set result [Misc_CheckPse $env(PSEPIN) $env(PSELOC)] while {$i == 0 } { if { $result == 1} { #putlogfile "The pse and pinn check OK" set i 1 } else { catch {unset env(PSELOC)} catch {unset env(PSEPIN)} if {[enter_pse_details ] == 0} { set recv_result "0" return 0 } else { set result [Misc_CheckPse $env(PSEPIN) $env(PSELOC) ] } } } } } set newpse [Get_PSE $local_sapenc_file $irand] #puts "$newpse" set tclcmd [ list exec secude pkcs7dec ] set tclcmd [concat $tclcmd -p $newpse] set tclcmd [concat $tclcmd -i $local_sapenc_file -o $local_enctxt_file ] #putlogfile "$tclcmd" set result [catch $tclcmd output] #puts "$output" if { $result == 1 } { #putlogfile "$output" } pkcs7_InterpretOutput $output pkcs7result #putlogfile "OK=$pkcs7result(ok) summary: $pkcs7result(summary)" if {$pkcs7result(ok) == 1} { ##putlogfile "keyid:$pkcs7result(keyid)" set recv_encstatus "success" set recv_enc_asym_keyid $pkcs7result(keyid) set tclcmd [ list exec secude psemaint -p $newpse own] set result [ catch $tclcmd ownerlist ] set ownerlist [regexp -nocase {PSE Owner: (.+)} $ownerlist {} ownerl] set tclcmd [ list exec secude psemaint -p $newpse export Cert $local_cert_file] set result [ catch $tclcmd certout] set tclcmd [ list exec secude asn1show $local_cert_file] set result [ catch $tclcmd certinfo] set certfile [open $local_cert_file w 0600] puts $certfile $certinfo close $certfile set certinfofile [get_cert_info $local_cert_file] set decmes ".\n Decryption: Success \n PSE OWNER DN: " set recv_encmessage [ concat $decmes $ownerl " .\n PSE Location:" $newpse ". \n Recipient Certificate information:\n" $certinfofile] #timedmsgpopup "Decr: $pkcs7result(msg)" "$recv_encstatus" 10000 } else { set recv_encstatus "failed" set recv_encmessage $pkcs7result(msg) set recv_enc_asym_keyid "none" set pkcs7result(msg) [pkcs7_ShortenOutput $pkcs7result(msg) $pkcs7result(summary)] #timedmsgpopup "Decr: $pkcs7result(msg)" "$recv_encstatus" 10000 set recv_result "1" return 1 } } proc Addx509-cert-alias {file dn } { global env set alfile "[glob -nocomplain [resource sdrHome]]/pks-als.txt" if { [file exists $alfile] } { #putlogfile "file exists" } else { set certfile "[glob -nocomplain [resource sdrHome]]/owncert" set test 100 set userpin $env(USERPIN) unset env(USERPIN) set tclcmd [ list exec secude psemaint -p $env(PSELOC).$test ] set result [ catch $tclcmd noofpse] set env(USERPIN) $userpin if { [regexp {Selected PSE not in MPSEFile\, valid only ([0-9]+) to ([0-9]+)} $noofpse {} start end] == 1 } { incr end for {set i $start} {$i < $end } {incr i } { set tclcmd [ list exec secude psemaint -p $env(PSELOC).$i own] set result [ catch $tclcmd ownerlist ] set ownerlist [regexp -nocase {PSE Owner: (.+)} $ownerlist {} owndn($i)] set tclcmd [ list exec secude psemaint -p $env(PSELOC).$i export Cert $certfile ] set result [ catch $tclcmd output ] set tclcmd [list exec secude psemaint -p $env(PSELOC).$i addpk $certfile] set tclcmd [list exec secude psemaint -p $env(PSELOC).$start addpk $certfile] set result [ catch $tclcmd output ] file delete $certfile #set owndn [concat "<" $owndn ">"] set out [open $alfile a 0600] puts $out $owndn($i) close $out } } else { set tclcmd [ list exec secude psemaint -p $env(PSELOC) own] set result [ catch $tclcmd ownerlist ] set ownerlist [regexp -nocase {PSE Owner: (.+)} $ownerlist {} owndn(1)] set tclcmd [ list exec secude psemaint -p $env(PSELOC) export Cert $certfile] set result [ catch $tclcmd output ] set tclcmd [list exec secude psemaint -p $env(PSELOC) addpk $certfile] set result [ catch $tclcmd output ] file delete $certfile #set owndn [concat "<" $owndn ">"] set out [open $alfile a 0600] puts $out $owndn(1) close $out } } regsub {\<} $dn {} test1 regsub {\>} $test1 {} certs #putlogfile "envUSER $env(USERPIN)" set tclcmd [ list exec secude cifcerts -p $env(PSELOC) -U -u $file ] #putlogfile "$tclcmd" set result [ catch $tclcmd output ] #putlogfile "$output" if {[regexp {.*Key added to PKList.*} $output testout] == 1} { if {[regexp {Found Certificate of (<[^<]*>).*} $output {} user] == 1 } { #putlogfile "$user" regsub {\<} $user {} test2 regsub {\>} $test2 {} user1 #putlogfile "$user1" set aliasn "$user1" set out [open $alfile a] #putlogfile "$user" puts $out $aliasn close $out } } else { # check to see if the Alias file exists set i 0 set out [open $alfile r] while { [gets $out line ] > 0 } { if { [ string compare $line $certs ] == 0 } { set i 1 break } } close $out set out [open $alfile a] if { $i == 0 } { if {[regexp {CN=.*} $dn test] == 1 } { puts $out $certs } else { set tclcmd [ list exec secude psemaint -p $env(PSELOC) ] set tclcmd [concat $tclcmd alias2dname ] set tclcmd [concat $tclcmd \"$certs\"] set result [ catch $tclcmd output ] close $out regexp {.* <(.+)>} $output {} user set out [open $alfile r] while { [gets $out line ] > 0 } { if { [ string compare $line $user ] == 0 } { set i 1 break } } close $out if { $i == 0 } { set out [open $alfile a] puts $out $user close $out } } } close $out } } proc Addx509cert {yourpse file dn pin} { global env ##putlogfile "$pin" set env(USERPIN) $pin ##putlogfile "envUSER $env(USERPIN)" set tclcmd [ list exec secude cifcerts -U -u -p $yourpse $file ] #putlogfile "$tclcmd" set result [ catch $tclcmd output ] regsub {\<} $dn {} test1 regsub {\>} $test1 {} aliasdn if {[regexp {} $inline {} issuer] == 1 } { set recvresult(issuername,$j) $issuer #puts "$j $recvresult(issuername,$j)" } elseif {[regexp -nocase {SerialNumber: .*([0-9]+) \(.*} $inline {} serialno] == 1 } { set recvresult(serialnumber,$j) $serialno #puts "$j $recvresult(serialnumber,$j)" incr j } else { set test "ignore" } } close $in file delete $local_info_file set test 100 set userpin $env(USERPIN) unset env(USERPIN) set tclcmd [ list exec secude psemaint -p $env(PSELOC).$test ] set result [ catch $tclcmd noofpse] set env(USERPIN) $userpin if { [regexp {Selected PSE not in MPSEFile\, valid only ([0-9]+) to ([0-9]+)} $noofpse {} start end] == 1 } { #puts "end $end" incr end #puts "end $end" for {set i $start} {$i < $end} {incr i} { #puts "i= $i " set tclcmd [ list exec secude psemaint -p $env(PSELOC).$i export Cert $local_cert_file] set result [ catch $tclcmd certout] set tclcmd [ list exec secude asn1show $local_cert_file] set result [ catch $tclcmd certinfo] set certfile [open $local_cert_file w 0600] puts $certfile $certinfo close $certfile get_cert_info $local_cert_file for {set k 0} {$k < $j} {incr k} { #puts "i=$i k=$k $certresult(serialnumber)" #puts "i=$i k=$k $certresult(issuername)" if { ([string compare $recvresult(serialnumber,$k) $certresult(serialnumber)]==0) && ([string compare $recvresult(issuername,$k) $certresult(issuername)]==0)} { set pse $env(PSELOC).$i #puts "i=$i k=$k test done $pse" break } } } } else { set pse $env(PSELOC) } if { [string compare $pse "none"] == 0} { set pse $env(PSELOC) } return $pse } proc Get_ownerlist { } { global env set test 100 set userpin $env(USERPIN) set ownerall "none" unset env(USERPIN) set tclcmd [ list exec secude psemaint -p $env(PSELOC).$test ] set result [ catch $tclcmd noofpse] set env(USERPIN) $userpin if { [regexp {Selected PSE not in MPSEFile\, valid only ([0-9]+) to ([0-9]+)} $noofpse {} start end] == 1 } { incr end for {set i $start} {$i < $end} {incr i} { set tclcmd [ list exec secude psemaint -p $env(PSELOC).$i own] set result [ catch $tclcmd ownerlist ] set ownerlist [regexp -nocase {PSE (.+)} $ownerlist {} ownerl($i)] set ownerall [concat "$ownerall<" $ownerl($i)] } } else { set tclcmd [ list exec secude psemaint -p $env(PSELOC) own] set result [ catch $tclcmd ownerlist ] set ownerlist [regexp -nocase {PSE (.+)} $ownerlist {} ownerl(1)] set ownerall $ownerl(1) } return $ownerall } proc Get_Owner_PSE { dn} { global env set pse "none" #puts "$dn" set test 100 set userpin $env(USERPIN) unset env(USERPIN) set tclcmd [ list exec secude psemaint -p $env(PSELOC).$test ] set result [ catch $tclcmd noofpse] set env(USERPIN) $userpin if { [regexp {Selected PSE not in MPSEFile\, valid only ([0-9]+) to ([0-9]+)} $noofpse {} start end] == 1 } { incr end for {set i $start} {$i < $end } {incr i} { set tclcmd [ list exec secude psemaint -p $env(PSELOC).$i own] set result [ catch $tclcmd ownerlist] set new [regexp -nocase {PSE Owner: (.+)} $ownerlist {} newown($i)] # puts "$newown($i)" if { [string compare $dn $newown($i)] == 0 } { set pse $env(PSELOC).$i # puts " newpse= $pse" break } } } else { set pse $env(PSELOC) } if { [string compare $pse "none"] == 0} { set pse $env(PSELOC) } #puts " PSE returned $pse" return $pse } z x<|xx00px~<8<>770 ;{>|?????? dd?4???????? dd?4???????pp ~~? ????????3?&?&? i,'3?? 0` 1I~3aC#0,3,@# @ @(@<@>P>x||8`D"@@`"f3!x3  @@@@   #   |40|40 |4?|4>4?>4>4>4x>,!?h 1????`@pXPL(Dd t&'F'pppp$))$@@ ? #7?p8? w{m55m{w?g/?? /}0,6/ý//////?///? ?8 qfr>R>| `tXtPt@t,t ttttsssss\Hl ܣL Q     vvvvvpvdvXvLv8v,v vvvuuuuuu|ulu\uTuDu.V/o012356 8* :B ;Z <r = > ? @ A B C D5 EP Fg K N O P Q S' V@ e h k q r u v2 yO zn } l  l #5 $N %h &l R Fl PcQ:qh,lb #ldzdd;8<GqM4Ni 2)H -lFll_l R sr: "#.+/C0Z1s23568: ;!<7=M>d?|@ABCDEFK\NtOPQSVe<hRklqruvyz}(A\lx.B  l#$!%;&l lUoP4o^:1DlxAll)A{1b& C  + - .%!/J!0k!2!5!7!8":)"<S">u"?"@"A"B"C#D3#F_#H#I#K#L#N$O7$Q`$R$T$$E%l%m%%%9&y&&&&.'P'm'''3(t( (()6)r))1))3*DP***+t+++!,T,,, -G-z- --).JL..^.y.{.}$/J/u////)0p0001Z11182Y222l20"2b273!L3"b3#v3$3%3&3'3*3.394>$4C;4HS4Mi4S4_4d4h4m4n4r5;5LlQ5f5|5555556676P6j66ll6G 6l56l 7-"70l87Q7l7l7dA7D7E7F7G7H7R8S,8T@8UV8Vm8W8X8Y8[l8l8l &9vl>9[V9999B:t:::/;_;;;;4<h<<< =9=^=== >>>>>?:?z???2@{@$@@A.6AAAA#B\BBBCCECCC DDDyDDD&E_fEEjEFoFFF)GeGGGH5HfHHHECHIUIIIII.JiJJJKKYKKKKALsLLL6MFMMMMNDN|NNNBOuOOO0P|PPPEQQQQ,RaRR:RR*SlSSSQ TR.TSQTT*SlSSTcTdUe@UT*SlSSUuUvUT*SlS"V^VVVVV7WyWWWWTAXsXTXX,Y7WiYYYZTXZZZ7WZ[7WA[|[[[7W+\V\T\\T)]s]7W]]T"^b^^T^|[&_V_!w_T^_+_7W `4K`7WA[|[&_`C`TaMAa7WaWaT bFbb[b7Wblb7Wc_cycTcd^dTdFbd7W$eVeeeTp>ppE(qhqLqq\ rMrrrdrri$ssosqsrsz%tQt~ttttuUuouuuu,vuvvvvwPwnwwwxTxxxx yCysyyy-zIz}zz5z#{R{r{<{{B|E|u|H||M|6}v}U}} ~[/~g~~`~b~j)[Pl]^3_b`a΀bc;duef݁l7{nł=^1P!SBnJӅ._Nwzy0TwlSS7Wg&Fh,q=v=Mی0]֍(V׎0]ʏ\2~ȑTrŒC} )E3u68̔;='>KAz˕]r\"Q?1XњlHX&S l}" &S l Ǜ&S l &S l. ?&S leC w& T lD &*U lלE &JV lF "&jW lIY&X l~k&X l: Ý&X l&X l,& Y lR e&*Y l &JY lĞ]Ӟ&jY l<&Y l*) ;& Z la t&@Z l &VZ lן &lZ l )&Z lQa&Z l &Z l ՠ&[ lT &.[ l=+ N&N[ ltA&n[ l$DlDDlDElDF8lDGXlDH|lDIlDJlDKlDLlDM lDN@lDO`lDPlDQlDRlDSlDTlDU lDV@lDWdlDXlDYlDZlD[lD\lD](lD^HlD_hlD`lDalDbl$ld!zd!d;!8<GqM4Ni 2ɡxH -F R sr:B ֡m )D025j666G 65~â2llɣVlI\,"DxϤl>pͥ C\ l:lv5{.*l[v$ ͨ 1llEe`ݩ_yLϫll)EE٬[ۭ'c׮3l7Ԥ¯,ٯ-./5:6V7r8;<ɰ=>D!E=FYGuJKḺMQRV2WlKI߳J-nŵk(r'allǸl,v'e<ƺ/OWĻV4ml{A6jʽ+lp]l־lllNſl="@O XCSl1lJI)`)c'c;s$sl,lllE{>eDlYllx lBp4^&Vl,$lR(<5FjlA IljlWglyX?oll4/Zl}@%]sllllllllll:Unlllll=mTl)pAz1cl)2/"2_7dA88 [CB::&/;_;;;q4<< ==x= >y:?#2@{@$k@A.AA#B\BB'CWECC DDDDD _MEj?)GeGGGH5H":ECzUIII#ZiJJKYKKKALsLQ6M E^DN|N'BOuOn=QMQR:.fSSQRS ffSTcdeffSUu&vJff"V^VVWfQfX YYBfZ [|[[fDfSfb^ fT|[V_!fT_+C4[|[`Cf MIWfFbbNl RyfQfFbIf/fv'gfJa$^LAkkGlll%mmY#I*2/s7=>>MEyL7\SMrrdi~oqrzGtKe"k F d    J u     Cysyy9 -^    5C #{  <  B2 t  H M'eU}[Bz`bj:lPl]^D_s`abcLdefl7{Hs9{>!wBJ$_Dwpy &fmSJ<^"gv,skی 7Y0Z 7d6 X   .!L!!!$"["")"3"6#8F#;u#=#>#A#F$$$$r%\%%%&2&d&&&&&'''%(s(((()4)`)l):))*Z*l****ll/+D+^+y+llll++l+M,?,n,,,,#-W----7.v...=/o///*0h0001?1p111$2[2223L333 4A4444-5b555676n6667\77ll77(8~88809M9999%:e:::;F;;;<<J<&_<<<<!=6=r===l;>O>lk>ll>$,!lD,lD-lD0lD1lD3HlD4PlD6XlD8\lD;llD=xlD?lD@>@->(.( >/>0lll$>$C\">@B>@BlDClDGlDJ "lD/,lD7,"lDK,lDL4lDM<lDNLlDQ`lDRhlDSxlDTlDWlDZlD[lD]lD_lDelDglDalDblDclDh?G?@H ?Ill,l,ll$4,?$k#lDklDo lDp lDrlDsl ll$$>?$v#V?@ulDvlDw lDx$l$,b?${#V?@z>@zlD{lD|lD~lDlD lD$lD<lD@lDXlDdlDh֡H$lD%hlD&hlDhlDhlDlD'`$lDlDlDlDlDlDlDlDlDlDlDlDlDlDlD(lD8lD<lDLlDllDplDtlDlDlDlDlD|?@|l?@lhlh?@&lhlll?llll$?$%lDlDlDlDlD$lD(lDLlD`?@??@ll`l$tld<&zd<&?d;<&8<GqM4Ni 2/+-FD+^+y+?$I<&@@IlDJlDKlDOlDQ lDR,lDP4lDS<@(N( ll<l$Pld&zd&8@d;&8<GqM4Ni 2ɡxH -F R sr:B ֡m25j666G 65I\ v5{.[v$Ee)7Ԥ'{p]־1JI),E{>Yx ,R(<5Fjjy4}@%]s:Un))2/"2_7dA88 ):**/+D+^+y++++MN@d@@l;>O>k>@$&&@@%lD&lD' lD(lD)lD+lD-,lD.0lD/4lD08lD2HlD3LlD4PlD6\lD4`lD9hlD:t@@'A@(l ltl$ A&=\ !A&>\ 4A$A'IA@@^A@@lDAlDBlDClDDlDE$lDF,lDG0lDI@lDJDlDKLlDLPlDOTlDP`lDQdlDShlDTlmA@Bllll$xA$W'A@VlDWlD[ lD]lD^$lD_0lD`8lDc<lDdPlDf\lDhhlDitlDjlDklDnlDolDqlDrlDsl$A$vL(A@ulDvlDwlDylDzlD{(lD}0lDHlDLlDTlDXlD\lDhlDplDtlDxlD|A@wA@wAxll|l$A$(B@B@lDlDlD(lD lD lD% 8@(lD lD4)lD8lD8lD%88@)lD8)lD@lD@lD%@8@)lD@lDDlDDlDLlDPlDTlD\lDhlDxlD&B5B@ll BB@l l l l8l8l8l8l@l@l@l@ll$ld`)zd`)LBd;`)8<GqM4Ni 220")H -F R sr:B 2b25j666G 657dA88 _B$Y`)rB@X|B@XB@XlDYlDlDl$B$x)rB@lDlD lDl$ld)zd)Bd;)8<GqM4Ni 2ɡxH -F R sr:B ֡m25j666G 65I\ v5{.[v$Ee)7Ԥ'{p]־1JI),E{>Yx ,R(<5Fjjy4}@%]s:Un))2/"2_7dA88 ):**/+D+^+y++++MBPBCPCCCCClC&0\  D$4)D@3lD4lD5 lD6l$%D$q)lDqlDr lDvlDw(lDx@lDzdlDyhlD{plD|tlD}t5D@r>D@sHD@sRD@tl ltl$[D&\ iD$(*~D@D@lDlDlDlDlD(lD8lDDlDHDllHl$LD$t*lDlD lDlD0lD8lD<l$DD$*lDlD lDl$ld*zd*Dd;*8<GqM4Ni 2 El-E-FbEEEFZFllFd2s$9 "#.+/C0Z1s23568: ;!<7=M>d?|@ABCDEFK\NFOFPFQGS&GV>GeGhGkGqGrGuHv#Hy>Hz[H}sHHHlHHHlBI,]IlxI6II5II/J!GJJJKUKKKLPLL]LLM6M_M{MMMMNTN|NNN O0OwOOP9PUPlPb7PP)QlQQQQ R/R NRllRRRll S<,'SeSSS'll++S+M l**2S!S"T#)T$>T%ST&jT'T*T.T9T>TCTHUMUS2U_HUd]UmuUnUr5ULlUUUUV&V=VTVmVVVVj666N 65lV-V0lVW3WlyNWXWWWolX--X HXlHltXXX* Y_lɡ4H  'YFlcB EY_YPYY#Z\ZZZ[^:E[[[[9\\\\l֡l0])i]0]])^W^^^VlI\ v5{.[v$Ee)7Ԥ'^<____+`<O````Oa_aV~aaml{p]־1J)b):bbbbc:cccc0dadddl,E{>YxǨel^eBeee3f\fff gl+EggglR(<5Fjgl*hAAh Ivhlj4}@%]s:Unhh0iliij>jjjjkLkklkk l(lhlllm4mkmmmnCndn nn+n-o.?o/ho0o2o5o7p89p:_p<p>p?p@pAqBJqCiqDqFqHqI rK4rL[rNrOrQrRrT)s|sssmtVtttu:uUuuuuvkvvv$w Ew~www:xYx1yxxyD%yeyyz^zzz!,T,{{{{| =|||J|7}^U}y}{}}}~B~v~~~p0Ow nĀ;2~l22]7dA88[F`B::/;_;;;74<z< = I= >̈́T:?ʅ2@{@$L@A.ԆAA#B\BBCAECC DDDƇDD_>jQ؉eGGGH5HNyECՊUIIFIiJJK1YKKKwALsL6MPҍDNZێBOuO%eAuǐQQF|:ʑISSQ’RS SISTcdeғSISUuv@SI"V^VVהVەS%YSXٖYYPSZΗ 4q|[[SbS>ySb^6S|[V_!S_+;y4q|[`CSFMǝWSTFbbӞlYyS3gSFb9wLSfߢ,'grSѣRؤLϥQ̦qkkܧ$lll%msmCj#*-zª2*7N=z>>īE;~L\Mrr]d­iQooqrǮz&Vpٯ7RȰ` CbʲMzг CysyyB-i5V#{<*BM¶H#MJͷU}J[pʸ`bPjpܹPl]W^_`a-bacdݻefKlb{ڼ4uֽWɾ!![BxJʿ_0w^ySeS<`%i7tE]{یu<jLw2r [<=T)368I;z=>ASr4w"TR[+Uxl):/+D+^+y+N8=wW7w;&Q+hl53B|$l;>O>k>l7&D\ H&E\ X&H\ i$[*lD[lD\lD]lD^lD_$z\ll$l$($b*@alDblDclDd(lDe<l$@$g4+@g>@glDglDhlDilDjlDk lDl$lDo(lDl,lDm,lDo0lDp4lDjLlDrXlDs`@h@h@ill`l$t x {   1 ?$+@L@lDlDlD$lD$lD,lD8lDDlDPlD\lDdlDdl@l$ldldl$|Z$$,k@z@@ @lDlDlDlD,lD4lDHlD\lDllDplDtlDlDlDlDlDlDlDlDlDlDlDlDlD lD<lDDlDHt-lD/PlD0PlD7`D-lD`lDdlD|lDlDlDlDlDlDlDlDlDlDlDlDlD(lD4lD@lD@@@@@llPl`l@l$p$.k@z@ @@lDlDlDlD$lD,lD@lDTlDdlDlDlDlDlDlDlD lD lD lDlD lD!lD"/lD/$lD0$lD74D/lD"4lD#8lD%TlD&\lD'llD)tlD,lD-lD.lD0lD1lD2@@ll$l4ll$*$:0B@5Q6hi@7u9llD?lDClDMlDOlDYlDflDg lDh8lDiPlDjhlDklDllDmlDnlDolDplDq lDr lDs8lDtPlDhlDlDlDlDlDlDlDlD4lD\4lDExlDFxlDGD04lDlDlDlDlDlDlDlD,lD4lD8lDPlDXlDhlDlDlDlDlDlDlDlD,lDHlD`lDlDlDlDlDlDlDlDlD$lD<lDHlDdlDhlDllD|lDlDlDlDlDlDlD4lDhlDlDlDlDlDlDlD  lD  lD 8 lD @ lD X lD` lDt lD lD lD lD lD( lD, lDD lD\ lD p lD" lD% lD' lD., lD/\ lD3p lD4 lD> lD? lD@ lDi4 lD4 lD\ lDt lD lD lD$lD,lD@lDHlDtlD|lDlDlDlDlDlDlDlD<lD@lDhlDlDlDlDlD`lDdlDxlDlDlDlDlDlDlD0lDDlDdlDlDlDlDlDlDlDlDlDlD$lD4lD<lD`lDxlDlDlDlDlDlDlD lD 8lD LlD dlD |lDlDlDlDlDlDlD lD,lD#lD%lD&lD'lD(lD) lD*4lD+TlD,lD-lD/lD1lD3lD5lD6lDAlDBlDF lDI0lDJPlDLXlDN\lDO`lDRdlDSplDYlDZlD[lD\lD]lD_lD`lDalDblDc4lDd8lDh<lDiTlDmlDnlDolDplDuDlDvllDzplD{lD|lD}lDlDlDlDlD lD0lDDlDXlDhlDplDlDlDlDlDlDlD4lDPlDTlDllDlDlDlDlDlDlDlDlD lDDlDLlD`lDtlD|lDlDlDlDlDlDlDlDplDtlDlDlDlD lD lD4lDHlDXlD`lDxlDlDlDlDlDlD(lD,lD@lDPlD|lDlDlDlDlDlDlDlDlDlD,lD<lDLlD`lDplDxlDlDlDlDlDlD lD lD @!lDt!lD!lD/!lD1"lD2";<d<=>?x#@@-@@7@AEAxhC`xDD\EFX@IJx@JKtL<MTOO|O@*P3@RzSlJT V@Ua&V\ @WX@YP@Z\\\] ]@^b^__@`a@abbl,lxll"l$<"8$6RD6P@7lD8lD9lD>lD?lDA(lDC4lDE@lDFLlDHTlDI`lDJplDKlDMlDNlDOlDPlDblDclDRlDWlDYlD\lD]$lD^$lD`4lD^HlDfTlDhTlDkhlDlhlDmtlDolDrlDtlDulDwlDxlD}lDlD(lD4lD@lDTlDhlD|lDlDlDlDlDlDlDlD lDlDlD,lD,lD,VlD0lD0lD0lD%DDVlDDlDXlDlDVlDplDplD%pDDVlDplDlDlDlDlDlDlDlDlDlDlDlDlDlDlD$lD(lD<lDDlDXlD`lDdlDxlDlDlDlDlDlDlDlDlDlDlDlD(lD@lDPlDlDlDlDlDlDlDlD0lD4lD 8lD<lDXlDhlDxlDlDlDlDlDlD lD#lD'lD(lD)lD-lD.0lD1<lD4@lD6PlD7XlD;dlD@plDAlDBlDClDGlDIlDLlDMlDNlDSlDTlDVlDWlDX lDYlDZ@9]@:n@<l@]l$lTklh@opp@pl@lll,l,@l0BB@l0lDlDlpBB@lplplp@llll$$]h[@\lD]lD^ lD_ lD` lDa,lDf0lDh<lDjP!&^d l lPl$P-$l[lDllDm lDpl$ F$r[lDrlDw lD}lD$lD8lDPlDTlDXlDplDl$`$|\u@lDlDlD$lD0lD@lDXlDdlDplDlDlDlDlDlDlDlDlD(lD8lDHlD\lDplDlDlDlDlDlDlDlDlD$lD4lD DlD LlD h^lDlDlD$lD%lDlDlD$lD%D<_lDlDlDlDlDlDlDlD(lD8lD!HlD-llD.xlD0lD1lD8lD9lD:lD@$lDAHlDBPlDCtlDDxlDFlDGlDHlDIlDJlDNllDOplDPlDQlDUlDVlDZlD[ lD\0lD^4lD`@lDa`lDblDclDelDhlDilDjlDllDmlDnlDolDs(lDtXlDyplDzlD{lD|lDlDlDlDlD,lDTlDllDtlDlDlDlDlDlDlDlDlD lD4 lD\ lD lD lD lD lD lD< lDL lD\ lDl lD lD lD lD lD lD lD lD( lD4 lD@ lDP lD\ lDl lDx lD lD lD lD lD lD lDL lDP lD` lDx lD lD lD( lD0 lD< lDD lDP lD lD lD lD lD lD lD lD lDlD lD$lD8lDLlD`lD llDtlD4lD6lD;xlD=lDglDhlDilDllDm lDnlDo lDq4lDullDvlDwlDxlDylDzlD{lD|lD}lD~lDlDlDlDlDlDlDlD lD lD4lDHlDXlD`4h0,V@ >@z8($ @@ @-@;Puth>`P@_PPoDDD llBB@llllBB@llll`l$$n@@@@lDlDlD<lDXlDhllhl$x$to%l5hAOZgw  $(,04'8=<P@lDlDDlDDlDxlDlD\lDlD lD (lD <lD\lDtlDlDlDlDlDlDlDlD,lDPlD$lD%lD)lD+lD,lD-lD.lD04lD3LlD;llD<lD=lD?lDClDDlDHlDJlDK@lDLPlDN`lDPlDQ ulDlDlDlD%D4ulDSPulDlDlDlD%DlulDUlDXlDYlDZlD[lD\lD^lD_lDblDclDdlDflDglDjlDllDmlDolDslDtlDu(lDw8lDx@lD{LlD}PlD~XlDdlDhlDxlDlDlDlDlDlDlDlDlDlD lD lD0 lD8 lD\ lD` lDh lDt lDx lD lD lD lD lD lD lD lD lD lDP lDt lDx lD lD lD lD lD lD lD lD lD lD lD lD lDP lDt lDx lD lD lD lD lD lD lD lD lD lD lD lD lD lD8 lD8 lDH lDX lD` lD lD lD lD lD lD lD lD lD lD lD lD 0 lD D lD T lD X lD lD lD lD lD lD lD! lD lD <lD# <lD$ LlD% \lD' `lD) dlD* llD, lD/ lD3 lD4 lD5 lD1 lD2 lD7 lD8 lD: 0lD; 8lD= TlD> plD@ tlDA |lDE lDI lDJ lDK lDL lDN lDP lDS lDT lDV lDQ lDR lDZ lD[ <lD\ LlD] XlD_ `lD` lDa lDb lDf lDi lDo lDp lDq lDk ,lDl XlDs XlDt hlDv xlDw lDz lD| lD} lD~ lD lD lD lD lD lD (lD 0lD PlD dlD hlD plD |lD lD lD lD $lD (lD 8lD HlD LlD PlD \lD dlD xlD lD lD lD lD lD lD lD lD lD lD lD lD $lD 0lD DlD TlD \lD tlD lD lD lD lD lD lD lD <lD @lD TlD `lD hlD lD lD lD lD lD lD lD lD lD lD lD ,lD @lD TlD hlD |lD lD lD lD lD lD lD lD lD 8lD HlD TlD dlD tlD xlD lD lD lD lD lD lD lD lD |lD lD lD lD lD LlD \lD tlD tlD lD lD lD lD lD 8lD HlD hlD lD lD! lD" lD# lD4 LlD5 lD# lD7 lD8 lD9 lD: 0lD= 4lD? DlD@ TlDA dlDC lDD lDF lDG lDH lDJ lDK $lDM HlDN TlDO dlDQ xlDR lDS lDT lDU lDV lDW (lDX @lDZ LlD LlD[ xlD^ lD_ lD` lDa lDb lDd lDf @lDg TlDh plDi lDj lDr  lDs  lDu $ lDv 4 lD~ D lD l lD lD lD lD lD lD lD !lD !lD $!lD 8!lD L!lD \!lD p!lD !lD !lD !lD !lD "lD ("lD T"lD "lD "lD "lD "lD "lD #lD 0#lD X#lD #lD #lD #lD #lD #lD #lD \$lD |$lD $lD $lD $lD 8%lD T%lD p%lD %lD %lD %lD %lD %lD %lD &lD &lD $&lD 4&lD P&lD &lD &lD &lD &lD &lD &lD 'lD 'lD ('lD D'lD x'lD |'lD 'lD 'lD 'lD 'lD 'lD (lD 4(lD `(lD x(lD (lD (lD (lD (lD (lD (lD (lD $)lD4)lDD)lD D)lD H)bj&d @@d`\X-dL|T\4P LH#D.@9 LlD? LlDB dlDC hlDD tlDE lDF lDG lDI lDL lDM lDO lDP lDT lDV lDW lDX (lDY 0lD[ @lD] PlDb XlDd dlDf tlDd xlDi lDk lDn lDq lDs lDt lDu lDw lDx lDz lD| lD} lD~ lD 4lD <lD LlD TlD XlD hlD plD lD lD lD lD lD lD lD lD lD lD lD lD lD lD lD $lD 0lD @lD PlD `lD llD lD lD lD lD lD \lDlDlD%D\lD lD lD lD lD lD lD ,lD <lD `lD hlD |lD lD lD lD lD lD lD lD lD lD @ @% @( V@) @* -@+ @, l$lBB@lllll$$   <  & 6 G U ` o     $lD lD ,lD 4lD8lD@lDLlDPlD`lDplDtlDlD lD lDlDlDlDlDlDlD lD" lD# lD$(lD%0lD&8lD'@lD*TlD.`lD0lD5lD8lD;lD=lD>,lD?0lD@4lDB8lDCLlDDXlDEhlDMlDOlDPlDQlDRlDUlDVlDWlDXlDYlDZ lD[lDglDi,lDj0lDk8lDl<lDmDlDpHlDqTlDrXlDs\lDvllDlD? @ @ @ @  @ & l l,ll$$p@lDlDlDlDlD,lD<lD@lDDlDPlD\lD`lDhlDllDxlDlDlDlDlDlDlDlDlDlDlDlDlDlDlDlD@lll$$dlDlD lD lD(lD0lD@lD\lDdlDtlD@l ll$$@lDlDlDlD(lD4lD8lD@&@ll@l$@/$4@lDlD lD lDlD,lDDlDHlDP&@l lPl$PO$@lDlD lD lDlD(lD@lDLlD\lDp&@l lpl$pn$@lDlDlDlD lD$lD4lD<lD@lD!PlD"T@llTl$`$)T@(@(>@(@(lD)lD*lD. lD9(lD;,lD<4lD><lDBDlDDLlDEhlDFlDGlDHlDIlDKlDNlDOlDQlDRlDSlDTlDU lDV(lDW0lD4lD4lD%4DlDW4lDXLlDYdlDZhlD[plD\tlD]lD`lDblDclDelDflDglDilDjlDllDm$lDo4lDmDlDq\lDrtlDtlDulDvlDzlD~lDlDlDlDlD@*+,-@.@.'/7@0@1ll4BB@l4l4l4ll$(G$|@lDlDlDlD lD$lD4lD<lD@lDPlDT@llTl$`_$ܪ@5>@w@%lDlDlDlD lD$lD,lD4lD<lDDlDLlDPlDTlD\lDxlDlDlDlDlDlDlDlDlDlDlD%DlDlDlDlDlD,lD0lD<lDPlD`lDllD|lDlDlDlDlDlDlDlDlDlDlD(lD8lDDlDTlD`lDllDlDlDlD@@ @@ @V@@llBB@lllll$$@lDlDlDlDlD lD;$lD<4lD$8lD%DlD&PlD'llD&tlD(lD)lD(lD+lD-lD.lD/lD0lD1lD2lD4lD5lD6$lD80lD94lD><lD?DlDDTlDH`lDIplDJlDIlDKlDLlDM@@@@Dlll$  P P! Q0 uR vz w y z | | | |  } ~* ; L q ldzd}d;8<GqM4Ni 2 " #&  l  l:E lfht l{ l( l# l#/ lP \ l~) l l l   l8'D lgRt lS lK l% l*S7 l['h lO l` l Sldzdd;8<GqM4Ni 2ɡxH -F R sr:B ֡m25j666G 65I\ v5{.[v$Ee)7Ԥ'{p]־1JI),E{>Yx ,R(<5Fjjy4}@%]s:Un))2/"2_7dA88 ):**/+D+^+y++++M54I$lj8Hsl;>O>k>$>lD>lD?lDClDDlDFHlDGPlDIXlDJplDLtlDNlDOlDP>@?@>(A >B>Clll$$SPV?@R@R$@R1@RlDSlDTlD\lD^(lD`8lDb@lDeLlDfdlDghlDhlDklDolDqlDrlDslDtlDu,lDy8lD{<lD}DlD~TlD`lDllDxlDlDlDlDlDlDlDlDlD lDlD@lDlDlDlDlD,lD0lDPlD\lDtlDlDlDhlDtlDlDlDlDlDlDlDlDlDATc@UsV,@V @V@V@V@WXY0lll$4 $lDlD lD lDlD0lD<lDDlDPlD`lDllDlDlDlDlD@l ll$$DlDlDlDlDlD lD8lDXlDdlDlDlDlDlDlD lD4lDDlDLlD\lD dlD llD tlD lDlDlDlDlDlDlD lD!lD"lD#lD'(lD(0lD)8lD+TlD-`lDdlD0plD1t@7@D@Tu@ lltl$$5$@4>@4@4lD5lD6lD7lD80lD;dlD<plD=lD?lD@6lll$$C$@B>@B@BlDClDDlDElDF0lDIdlDJplDKlDMlDNDlll$$Ql$@P>@P@PlDQlDRlDSlDT0lDWdlDXplDYlD[lD\/Rlll$Q$_0>@^@^lD_lD` lDal$e$dD$@c>@c@clDdlDelDflDh0lDj8lDmllDnxlDolDqlDrelll$$lDlD lDl$ $4@ lDlDlDlDlDDlDLlDTlD\lDdlDplDt@lltl$| ;ldzdd;8<GqM4Ni 2% E):4vK_t lH -F R sr:B ־l/+D+^+y+3ll 6Kllll֡m25j666G 65I_5"MxpJCF lv5{.[v$Ee)7Ԥ'{p]llR(<5Fjj+++M%]s:Un+**l,E{>Yx 1D[w>U@xlllɡxJI),y4}@\:x3Tl)2/"2_7dA88[.tB:$:`/;_;;;4<<" =X= >C f  :? @ y 2@{@$ @A. J AA#B\BB C EC C DDD< DDr _  j o  #PeGGGH5H ECOUIII6iJsJKYKKKALsL56M 1LDN WBOuO'tCQQ.:JSSQBRfSSTcd*eRSUuv"V^VV 1W7[#XYYYZN|[[.l+r'sb^ |[? V_!p  _+  48!|[? `Cy!!M"G"W""Fbb#S#l##"$yf$$$+%w%Fb%%+&x&&'f_'''g'9(Q((()X)))*O*** +L+++ ,kk\,,lll%m,8-m{---#/.u.*..D/2e//7/=/>(0>F00E01LA11\1Mrr1d2F2io22o2q 3rL3z|333304^4~444505M555 6'6H66667Q777808Y8 8Cysyy8-8=9s9959#{:@:<r::B:;K;H~;;M;<V<U<}<[<2=S=`z=b==j=/>f>Pl/+54j8;>O>k>> <> => >>$@lD@lDN l$>$Q?@P?@Pz@P?@PlDQlDR lDU lDW4lDX@lDYHlDZ\lD\hlD]xlD`lDb`lD/lD0lD7plDblDclDdlDjlDflDl(?Rl llll$4?$oԽ?@n>@n D?@nXnlDolDu lDx lDy$lD~4lDDlDPlDTlD`lDdlDhlDllDplD|lDlDlDlDlDlDlDlDlDlDlD lDlD lD(lD@lDXlD`lDplDxlDlDlDlDlDlDlDlDlDlD lD<lDDlDHQ?&ul d?(v ?(w܏ ?@x?@y?@y?@y@yyl lHl$?$X?@lDlDlDlD lD8lDXlD`lDhlDplDxlDlDlDlDlDlDlDlDlDlDdlD lD lD lD%tlDlD |lD$lD$lD$lD%4lD4lD8lD<lD<lD<lD%LlDLlDPlD \lD dlDplDtlD|lDlDlDlDlDlDlDlDlD lD!lDlD$lD'lD)lD*lD,lD-lD.,lD/8lD0<lD1@lD2HlD3PlD5TlD7XlD8\lD:`lD;dlD=llD>llD@xlDAlDBlDDlDElDFlDGlDHlDJlDKlDLlDMlDOlD$lDRlDS0lD\0lD^@lD_P @(, @@1@(0 @>@@lT@b@,@@@@@@@ l@l BB@l ll@l$BB@l$l4l4@l<BB@l<lLlL@@ll@@,llH@@=llll0lPl$l@$b?@alDblDclDflDglDh$lDi0lDj8lDk<lDl@lDnDlDoLlDpTlDqdlDrllDstlDtlDulDylD{lD|lD}lD~lDlDlD@@c@@c@@c A&dl A@e)A@elll$0;A$?@lDlDlDlD$lD8lDLlD\lD`lDdlDtlDxlD|lDlDlDlDlDlDlDlDlDlDQAlll$bA$?@lDlDlDl$zA$?@lDlD lD$l$,A$rB@?@A@lDlDlDlDlD(lD0lDDlDLlD`lDhlD|lDlDlDlDlDlDA@lll$A$A@z@lDlDlDlDlD$lD<lDDlDLlDllDtlDlDlDLlD/lD0lD7\lDlDlDlDlDlDlDlDlD%lDlDlDlDlD lD8lD<lD@lD@lDDA@A@lll@lBB@lllBll@lDl$`B$z@lDlDlDlD lD0lD8lDHlDPlDXlD`xlD/hlD0hlD7xlDxlD|lDlD lD lD lDlDlDlDlDlDlD%B@Allhlxll$</B$"LEB@!lD"lD#lD$lD%lD& lD($lD&8lD+DlD.LlD/`lD0llD1tlD2lD3lD4lD5lD6\B#iB@$uB$lll$B$9B@8lD9lD:lD;lD<lD= lD>(lD?,lD@4lDA8lDB@lDCDlDDLlDEPlDFTlDG\lDH`lDIdl$hB$Q|B@P>@PlDQlDRlDTlDU lDV(lDW<lDXHlDWL֡lD%PlD&PlDPlDPlDdlD&dlD'hlDZhlD[tlD\|lD]lD_lD`lDclD`lDalDdB@RB@RB@SlB@YlPlPB@&lPldlhlhll$C$gTB@fC@f0C@f>C@flDglDhlDjlDk,lDl8lDrDlDu\lDvtlDzlD{lD|lD}lDlDlDlDlDlDlDMC@hZChkC@illl$wC$$B@C@C@C@ClDlDlDlD lD<lDDlDHlDXlD\lD`lD|lDlDlDlDlDlDlDlDlDlDlDlDlDlD@C@lll$C$8C@lDlD lDlD$lD$l$,C$dC@C@D@ D@"D6DHD TDcDpDlDlDlDlD$lD0lD4lD8lDHlD\lDplDxlDlDlDlD$lD(lD,lD8lD<lDHlDLlDLlDXlDxlDlDlDlDlDlDlDlDlDlDlDlDlDlDlDlDlDlDlDlDlDlD lD $֡lD%0lD&0lD0lD0lD@lD'@lD @lD HlDL֡lD%XlD&XlDXlDXlDllD'llDllDtlD|lDlDlDlDlDlDlDlDlD lD$lD%lD&lD'lD(lD)lD*lD+lD,lD-lD.lD0lD1(lD24֡lD%XlD&XlDXlDXlDhlD'hlD3hlD4plD5lD6lD7lD8lD9lD:lD;PlD<\lD=llD>xlD?lD@lD@lDDlDElDGD@D@D@D@lB@ l0l0B@&l0l@l@l@B@lXlXB@&lXlllllllXlXlXlhlhlhll$D$K DID@ID@ID@J DJHDJlDKlDL lDM lDN(lDO8lDP<lDQPlDPTlDV`lDWxlDXlDWlDYlDZlD\lD]lD^lD_lD`lDalDclDdlDelDflDglDhlDi lDjlDklDl,lDm0lDnDlDoHlDpHlDtPlDuTlDvllDwxlDylDzlD|lD}lD~lDlDlDlDlDlDlDlDlDlDlDlD֡lD%lD&lDlDlD$lD'$0lD$lD,lD0lD8֡PlD%DlD&DlDDlDDlDTlD'T`lDTlD\lD`lDllDxlD֡lD%lD&lDlDlDlD'lDlDlDlDlDlDlDlDlDD@LD@LD@Ll B@llB@&ll$l$l$B@lDlDB@&lDlTlTlTllllllll$4 E$@'E@5ETCEPOE@ bElDlD lD lD(lD,lD4lD<lDTlDhlD|lDlDlDlDlDlD lDlD lD$lD,lD0lD@lDTlD\lDdlDxlD/lD0lD7lDlDlDlDlDlDlDlDlDlDlD lD lD lD lD  lDlDlD lD,lD0lD@lDLlDTlD#TlD$\lD%dlD&lD'lD(lD*lD,lD-lDn lDpLlDrXlDwdlDxllDtlDlDlDlDlDlDlDlDlDlDlD$lD(lD8lDHlD}LlD~XlD}plD|lDlDnE}E@%B@@E@E@EE`E@l llEE`E X@!lTE@%F@%ldlE@'F@'lllll$(F$rB@BF@A@ CERFlDlDlDlD$lD(lD0lD@lDPlD|lDlDlDlDlDlDlDlDlDlDlD@ll|lll$_F$rB@?@lDlDlDlD4lD8l$@F$ F@>@lDlDlDlDlD$֡dlD%DlD&DlDDlDDlDXlD&XlD'\|lD\lDhlDxlDlDlDlDlDMC@FB@llDlDlDlXl\l\ll$F$F@>@lDlD lDlDlDlD0lD8lD<lDDlDHMC@l lHl$PF$@lDlDlDlDlD$lD<lD@F(0 E G@ll@l$PldzdGd;8<GqM4Ni 2ɡxH -F R sr:B ֡m25j666G 65I\ v5{.[v$Ee)7Ԥ'{p]־1JI),E{>Yx ,R(<5Fjjy4}@%]s:Un))2/"2_7dA88 ):**/+D+^+y++++M54;>O>k>-Gl=GltGlG$=lD=lDElDHlDK8lDL\lDMdlDNplDQlDSlDTlDUlDVlDWlDXlDY lDZ,lD[8lD\DlD]PlD^\lD_hlD`tlDalDblDdGEG@FGGlll$H$gd1H@fAH@fRH@flDglDklDl$lDr4lDsDlDvlDwlDxlDzlD{lD|lD}lD~lD lDlD lD$lD8lD<lldHlltHpHpHpl$l l<l$LH$H@H@z@?@HlDlD lDl$H$H@z@RH@lDlD lDl$I$H@ z@RH@lDlDlD4l$8ldzdId;8<GqM4Ni 2)H -F R sr:B 2I$HI@lDlD lDlD lD lD lD $l ll l$l$0ld@zd@^Id;@8<GqM4Ni 2ɡxH -F R sr:B ֡m25j666G 65I\ v5{.[v$Ee)7Ԥ'{p]־1JI),E{>Yx ,R(<5Fjjy4}@%]s:Un))2/"2_7dA88 ):**/+D+^+y++++M54-G;>O>k>nI$1@I@1I@2I@3I@4lD5lD6֡TlD%lD&lDlDlD,lD',^IllD6,lD7DlD8Hlllll,l,l,lHl$TI$;I@;I@<I@=I@>lD?lD@lDA(lDB,l$4I$ElDElDF lDG lDHlDI,lDJ0@Fl l0l$<I$MI@MI@NI@OI@PlDQlDRlDSlDT lDU8lDV<ll<l$DJ$YHI@YI@ZI@[I@\lD]lD^lD`֡\lD%lD&lDlDlD,lD',^ItlD`,֡tlD%,lD&,lD,lD,lDDlD'D^IlD`DlDaTlDdhlDetlDg|lDhlDl?@^lllll,l,l,l,l,l,lDlDlDll$*J$oI@oI@pI@qI@rlDslDtlDx֡lD%lD&lDlDlD0lD'0^IlDy0֡lD%0lD&0lD0lD0lDHlD'H^I lDyHlDzdlD{plD|t%B@tlllll0l0l0l0l0l0lHlHlHltl$|IJ$TI@I@I@I@lDlDlD֡llD%lD&lDlDlD0lD'0^IlD0֡lD%0lD&0lD0lD0lDHlD'H^IlDHlD`lDdlDhlDllDxlD|?@lllll0l0l0l0l0l0lHlHlHl|l$fJ$I@I@I@I@lDlD lDlD l$(}J$I@I@I@I@lDlDlDlD lD,lD0lD0lD8lD<Jll<l$HJ$HI@I@I@I@lDlDlDlD lD8lD<lDH֡lD%HlD&HlDHlDHlD`lD'`^IlD`lDtlDlDJllHlHlHl`l`l`ll$J$lDlDlDlD ֡lD%$lD&$lD$lD$lD8lD&8lD'<^IlD<lDHlDXlDdlDlDlDlDlDlD֡lD%lD&lDlDlD lD& lD'^IlDlDlD0lD<lDTlDhlDtlDlD@J@J`ll$l$l$l8l<l<llll llll$J$I@I@I@I@lDlDlD֡lD%lD&lDlDlD,lD&,lD'0^IlD0lDLlD XlD llD pJ@lllll,l0l0lpl$K$,I@I@I@I@lDlDlD֡DlD%lD&lDlDlD,lD&,lD'0^I\lD0lDLlDXlDllDpJ@lllll,l0l0lpl$K$I@I@I@I@ lD!lD"lD#lD$$lD%,lD&04K("X ll0l$DBK$)I@)I@*I@+I@,lD-lD. lD/lD0l$ XK$3I@3I@4I@5I@6lD7lD8lD9$lDlDlD%^I$lD:lD;8lD<<llBB@llll<l$DnK$?TI@?I@@I@AI@BlDClDD lDElDFl$$K$IxI@II@JI@KI@LlDMlDNlDQlDSlDT$lDU,lDV0K(NX ?@Oll0l$<K$YI@YI@ZI@[I@\lD]lD^ lD_lD`l$K$cI@cKdI@eI@flDglDklDn,lDo<lDp@lDqPlDrTlDsdlDthlDuxlDv|lDwlDxlDylDzlD|lD~lDlDlDlD lD,lDplDxlDlDlDlDlDlDkkdHkKlKlK@l L@l L@l$L@l3Lllll$HL$I@I@I@I@lDlDlD,lD<lD@lDPlDTlDxlDlDlDlDlDlDlDlDlDlDdHaL@nL@3Llll$~L$I@I@I@I@lDlD lDl ll$L$I@I@I@I@lDlDlDlDlD(lD,L@ll,l$4L(` L(| #M( JM(? ldzdsMd;8<GqM4Ni 2ɡxH -F R sr:B ֡m25j666G 65I\ v5{.[v$Ee)7Ԥ'{p]־1JI),E{>Yx ,R(<5Fjjy4}@%]s:Un))2/"2_7dA88 ):**/+D+^+y++++M;>O>k>MoM M M &M SlN&6n +N&7n Yx ,R(<5Fjjy4}@%]s:Un))2/"2_7dA88 ):**/+D+^+y++++M;>O>k>-G=GYO 3iO 4zO ;O$@I@@OAhI@BI@ClDDlDE lDU lDV0lDW<lDYHlDZTlD\`lD]tlD_|lD`lDelDklDllDnlDolDplDrlDs$lDx<lDyPlD{hlD|lDylD~lDlDlDlDlDlDlDlDlDlDlDlDlD,lD0lD8lD@lDPlD\lD`lDdlDh֡dlD%hlD&hlDhlDhlD|lD&|lD'HO|lDlDlDlDlDlDlDlDlDlDlDlD/lD0lD7HOlDlD lD lD<lDHlDXlDplDlDlDlDlDlD(lD8lDDlD`lDhlDllDxlDlDlDlDlDlDlDlDlDlDlDlD lD$lDHlDHlDLlDTlDplDlDlD lD lD lDlDlDAlDE(lDH8lDJHlDKdlDLplDMtlDNxlDOxlDPlDQlDSlDTlDXlD_lD` lDclDdlDf,lDg<lDrDlDs\lDthlDulDwlDxlDylD{lD| lD>lDC$lD$lD8lD<OEO@FO@FO@FO@FP@FPG#P@H%B@J@J8P@JJPJlWP@KgPNrPOE@Pl P@Pllhlhlhl|llll@@PPAxlHE@P@lTlpE@P@llP pPtllxl,lhl<l$`P$\I@Q@Q@lDlDlD lD(lD<lDLlDPQ@llPl$\(Q$I@I@I@I@lDlDlD֡lD% lD& lD lD lD4lD'4HOlD4֡lD%@lD&@lD@lD@lDTlD'THO lDTlDplDxlD|HQ@ll l l l4l4l4l@l@l@lTlTlTl|l$\Q$DlDlD lDlDl$$wQ 7ldhzdhQd;h8<GqM4Ni 2)H -F R sr:B 20"2b25j666G 657dA88 Q$hlDlD lD l$Q$ |Q@ |B@ lDlD lD lDlD4lD@lDTlDllDlDQ( l ll$ld$zd$Qd;$8<GqM4Ni 22-Fsr:5j666G 65Q3 R#R7R!lKRx`ZRRRRRSCS_SS!lS=SS#lRT& ,o cT zT&4o T&8o T$$lDlD lDl$T$-@T@T@>@lD-lD.lD1lD2,lD50lD68lD7HlD;PlD=plD@lDBlDClDDlDElDFlDHlDJlDKT@.T1U@2lll$U$] %U@NlD]lD^ lDk lDllDm,lDn@lDoTlDphlDq|lDrlDulDwlDylDzlD{lD|lD}lDulDlD@^C@_l ll$1U$@U@lDlDlDlD lD lD,lDDlDTlD`lDllDllDxlDlDlDlDSU@lrUl llll$U$U@U@lDlDlD(lD0lD@lDLlDPlDXlD\lDdlDplDlDlDlDlDlDlDUT@U@@U@lll$U$|U@T@>@lDlD lDl$U( V ldzd-Vd;8<GqM4Ni 22-Fsr:5j666G 65־H  R B Q3 S=:V&;lD?lD@ lDAl$'X$F  X@F:X@GW@HlDIlDJ lDKl$ld zd GXd; 8<GqM4Ni 22-Fsr:5j666G 65ɡxH  R B ֡mI\ v5{.[v$Ee)7Ԥ'{p]־1JI),E{>Yx ,R(<5Fjjy4}@%]s:Un))2/"2_7dA88 ):**/+D+^+y++++MBPQU ZXtXX!lS;XX#l;>O>k>:Y&2|o Y$[ Y@ZlD[lD\lD]lD^ l$(Y$aH lDalDb lDcl$Y$g` Y@eY@eZ@eZ@flDglDhlDl lDp0lDq4l$8"Z$s 7Z@rCZ@rOZ@rlDslDtlDylDz$lD0lD4lD@lDHlDPlDTlD`lDplDlDlDlDlDlD_Z@upZ@vZ@wlll$Z$H 7Z@ CZ@ZlDlDlDlD$lD0lD<lDLlD\lDllDtlDlDlDlDlDlDlDlDlDlDlDlDlDZZ@ZZ@>@lll$Z$X [@lDlDlD(lD8lD<l$H[$  Z@ )[@ lD lD lDlD$lD<lDLlDTlDXlD`lDdZ@ lldl$l9[$ )[@Z@lDlDlDlD $lD"<lD#LlD%TlD&XlD'`lD(dZ@lldl$lQ[$,x Z@+)[@+lD,lD-lD3lD5$lD;<lD<@lD>HlD@XlDAdlDBhlDCllD7plD9lDFlDGlDHlDIlDKlDLlDMlDNlDOlDPlDQlDR lDS$Z@-ll$l$4e[$W)[@VlDWlDXlDZlD\$lD^8lD_@lD`HlDaPlDbXlDc`lDdhlDeplDftlDh|lDilDjlDkZ@Xlll$w[$n@lDnlDolDqlDrlDwlD8lD<lD@lDHlDPlD\lDhlDllDtlDlDlD%GXlDlDlDlD%GXlDlDlDlD%GXlDlDlDlDlDlDlDlDlDlD@lDDlDH[@o[@pZ@q[@r[s@tllBB@llllBB@llllBB@llllHl$`[$lDlDlDlD$lDE0lDF0lDG@GXlD@lDLlD\lD`lDhlDplDlDlDlDlDlDlDlDlDlDlDlDlDlDlDlDlDlD%GXlDlD lD lD% GXlD lD8lD8lD%8GXlD8lDPlD`lDtlDlDlDlDlD[@Z@[@[[@E@ \x\ll0l@lBB@llll BB@l l l l8BB@l8l8l8ll$$\$>\@P\d]\hZ@h\z\lDlDlDlD$lD (lD@lDTlD\lDhlDplDxlD lD!lD#lD%lD&lD'lD)lD*lD+lD,lD-lD.lD/lD lD lD% GXlD/ lD3$lD4HlD5XlD6plD7tlD8lD9lD;lD=lD>lD@lDAlDB$lDE8lDBHlDH\lDIplDKlDLlDKlDMlDNlDOlDRlDSlDZlDdlDe$lDf0lDg@lDhPlDi`lDmplDolD|lD~lDlDlDlDlDlDlD lDlD(lD4[@\@\@\@Al\\\t@\@@]\]@']@2]`ll BB@l l l l4l$DB]$>\@[]Z@lDlDlDlD lD(lDE4lDF4lDGDGXlDDlDPlDllDtlD|lDlDlDlDlDlDlDlDlDlDlDlDlDlDlDlD lD$lD,lD<lDDlDLlDTlDdlDhg]@[@t]@ E@]t]@]@\@\ll4lDlhl$x]$<lDlDlDlDlD lD,lD8lD@lDLlDXlD`lD plD |lDlDlDlD lD"lD#lD%lD']]t^@^@"^p\xlll$0^$*(lD*lD+lD.lD/lD0 lD3$lD4(?^@+K^@+W^,ll(l$,e^$7TZ@6t^@6lD7lD8lD9lD:$lD<0lD=4l$8^$BZ@BlDClDDlDGlDHlDJ(lDK@lDGHlDNTlDOXlDNdlDRplDSt@DC@Elltl$|^$q^@l^@m^@n^@plDqlDrlDslD{ lD}$lD~HlDHlDPlDTlD\lD`lDdlDllDxlD|lDlDlDlDlDlD}lDlDlDlDlDlDlDlD^@rE@s^@t^&v p l_@~ lHlll$)_$ ?_J_W_@lDlDlDlD0lD<lDDlDLlDPlDXlDllDtlD|lDlDlDlDlDc_@m_@{_@lll$_ O_ Pldzd_d;8<GqM4Ni 22-Fsr:5j666G 657Ԥ1_l_"_x`p`p``+aCcaaa (bl'dbKRx`wbjb&$Pp b&9Pq b&NPr b&cPs b&xPt b&Pu b&Pv b&Pw lc 'c&*Tx Jc&:y Vc$ccP\oc{ccclDlD$lD$lD(lD,lD4lD<lDHlDHlD%H_lDHlDl0lDlDlD%_0lDlDlDlDlDlDlDlDlDlDPlDlDlD lD lD lD( lD8 lD@ lDP lD\ lD\ lDd lDp lD lD H%lD lD lD% _H%lD lD  lD lD lD lD lD#$ lD$4 lD#4lD&HlD+LlD.\lD0|lD3xlD+lD6lD;lDBlDDlDGlDMlD;lDP lDU lDX lDZ 'lD]@'lDUP'lD`d'lDeh'lDlx'lDo'lDq.lDt.lDe.lDw.lD|.lD.lD5lD|6lD6lD(6lD06lD86QlDD6lDD6lD%D6_QlDD6lDh6 RlDt6lDt6lD%t6_ RlDt6lD6\RlD6lD6lD%6_\RlD6lD6lD6c@c( c($ c&y d&y d( +d( ;dWdsd@ d@d@ddl$d@d@d@l<lHBB@lHlHlHlld@d@d@lllBB@lllld@d@ld@d@d@llLd@e@d@lPlle@e@&e@l l\ d@d@d@l l BB@l l l l Ee@$Oe@$ Ye@$ge@$ue@$l4 e@$l( l l4Ee@0Oe@0 Ye@0ge@0ue@0l|e@0lhlPlxEe@DOe@D Ye@Dge@Due@Dle@DlllEe@XOe@X Ye@Xge@Xue@Xl e@Xl#l#l 'Ee@oOe@o Ye@oge@oue@ol'e@ol|*ld+l.Ee@Oe@ Ye@ge@ue@l.e@l1l2l5d@d@d@l86lD6BB@lD6lD6lD6lh6d@d@d@lh6lt6BB@lt6lt6lt6l6d@d@d@l6l6BB@l6l6l6l6l6l$6ldRzdRed;R8<GqM4Ni 2ɡxH -F R sr:B ֡m25j666G 65I\ v5{.[v$Ee)7Ԥ'{p]־1JI),E{>Yx ,R(<5Fjjy4}@%]s:Un))2/"2_7dA88 ):**/+D+^+y++++M;>O>k>-Ge$RlDlDlDlD lD,lD#8lD%DRlDEDlDFDlDGTeRlD%TlD&`lD'llD*lD+[[llDlTll$e$.,SV?@-e@-e@-lD.lD/lD2lD3(lD6<lD7TlD8\lD9hlD:llD;xlD<lD=lD>lD@lDBe@/E@0lll$e$GSf@Df@DAD'f@EZE2fFCEF ?fFlDGlDH$lDKDlDPLlDTdlDXllD^xlD_lDalDblDtlDuJf@EaL@FP@F WfHl$ll$ff$yUV?@xzf@x>@xf@xlDylDzlD{lD~lD lD,lD4lD@lDLlDPlD\lDdlDplDlDUlDlDlD%eUlDlDlDlDlDlDlDf@zf@{f@|llBB@lllll$f$UV?@f@lDlDlDlD lD(lD0lD4lDHlDXlD`lDhlDlf@f@llll$pg$DV%g@zf@3g@lDlDlDlD0lD<lDDlDHlDTlD\lDplDtlDxlDlDlDlDlDlDZCglll$Rg$WI@jg@I@I@lDlDlDlD8lDPlD`lDdlDxlDlDlDlDlDlDlDlDlDlD$֡,XlD*$lD+$lD$lD$lD8lD+8lD,@eHXlD@֡HXlD%@lD&@lD@lD@lDTlD'Te\XlDTlD d֡lXlD%dlD&dlDdlDdlDxlD&xlD'eXlDlDlDlDlDlD8lDLlDTlDTlD hlD!tlD"|lD#lD)lD*lD+lD,lD2lD4lD8\lD9plD:|lD;lD<lD=lDAlDDlDElDFlDHlDM(lDNLlDQtlDSlDTlDVlD[lD\lD]lD^lDalDclDelDf,lDh4lDk<lDmdlDolDplDrlDulDvlDwlDxlDzlD{lD|lD~lDDlDXlDllDlDlDlDlDlDlDlD$lDPlDtlDlDlDlDlDlD lD$lDplDlDlDlDlD lD lDL lDd lDX lD lD lD g@?<8gADZg4@g@ gg|glh5hL([h0ll$l$l$l8l@l@l@l@l@lTlTlTldldldlxlll l$ ih$alDlD lDlDlD l$(xh$ bI@h@I@I@lDlD lDl$h$8bI@h@I@I@lDlDlD lD$l$(h$`bI@h@I@I@lDlD֡tblD%lD&lDlDlD,lD',eblD,lDPlDTlllll,l,l,lTl$Xh$bI@h@I@I@lDlD֡blD%lD&lDlDlD(lD'(eblD(lD4lD8lllll(l(l(l8l$<h$bI@h@I@I@lDlD֡clD%lD&lDlDlD,lD',e clD,lDHlDLlllll,l,l,lLl$Pi$DcI@h@I@ I@ lD lD  lDl$"i$\cI@h@I@I@lDlD lDl$7i$tcI@h@I@I@lDlDlD lD!lD"lD# lD$ lD&,lD'0ll0l$<Ki$*clD*lD+ lD,l$_i$/clD/lD0 lD1l$yi$4cI@4h@5I@6I@7lD8lD9lD:8lD;HlD<XlD=\Z9ll\l$hi$?@dI@?h@@I@AI@BlDClDDlDE8lDFHlDGXlDH\iDll\l$hi$Ldzf@JiJ3g@J %g@JlDLlDM lDT$lDV(lDY,lDZ0lD[8lD\<lD_`lD`xlDc|lDdlDflDjlDklDllDmlDnlDolDplDqlDrlDslDvlDw lDx(lDy4lDz<lD{@lD|PlD}XlDtlD|lDlDlDlDlDlDlDlDlflDlDlD%elflDlDlDlDlDlDlD$lD0lD@lDHlDLlDPlD\lDllDtlDlDlDlDlDlDlDlDlDlDlDlDlDlDlDlD(lD0lD4i@Mi@NjOj@Pj@Q f@R-j@S=j@TUVl lBB@llll4l$LMj$gfjirj@f@ ]\|jlDlD lD$lD(lD4lDLlD`lD|lDlDlDlDlDlDlDlDlDlDlD lDlD lD,lD8lDHlDTlDXlDdlDplD|lDlDlDlDlDlDlDlDlDlDi@i@jj@j@j@j@l ll$j$jj@rj@f@j@|jlDlD$lD$lD0lDHlD\lDxlDlDlDlD lD lD lD lDlDlDlDlDlDlD lDlD (lD"8lD#HlD$\lD&dlD'hj@ i@i@jE@j@l$lhl$xldkzdkjd;k8<GqM4Ni 2 E2-Fsr:5j666G 65ɡxH  R B ֡mI\ v5{.[v$Ee)7Ԥ'{p]־1JI),E{>Yx ,R(<5Fjjy4}@%]s:Un))2/"2_7dA88 ):**/+D+^+y++++MBPQU S;;>O>k>k 7k 83k 9Ik :^k ;sk$Hkk@E>@E kEk@FkFkGlDHlDI lDM lDR$lDS0lDU<lDYHlD[dlD_tlD`lDblDclDdlDelDglDhlDklDllDnlDslDt,lDu<lDzLlD{TlD|\lDpdlDq|lD}k@Il@Kl@K&l@L7l@Ml ll$Ll$8mill@lllll kklDlD$lD$lD0lD<lDHlDTlD`lDhlDplDxlD|lDlDlDlDlDlDlDlD lD,lD4lD<lDTlD\lDdlDxlD|lDlDlDlDlDlDlDlDlDlD lDlD 4lD<lDDlD\lDllDplD|lDlD lD(lD)lD!lD%lD&lD-lD.lD/@l@l@l@ m@m@*m@9m@Hm@7l@l@\mkm@ {m&l@l$ll$0m$8hpm@7m@7 k@7lD8lD9lD=lDE lDF,lDG8lDIDlDNPlDOplDRlDWlDXlD\lD]lD_lD`lDaPqlDElDFlDGj`qlDelDflDh lDi(lDk0lDm8lDo@lDpLlDxTlDyXlD{dlD|plD|lDlDlDlDlDlDlDlD`rlDElDFlDGjprlDlDlD0lD8lD@lDLlDTlD\lDdlDllDplDxlD|lDlDlDlDlDlDlDlDlDlDlDlDlD$lD,lD4lD@lDLlDLlDhlDllDllDlDlDlDl@9l@9m:m;,m@<m@=l@= n=(km@>{m>$n@>*n@?l:n@cllIn$llll$Wn$,tlwnk@nnlDlD lD$lD0lD<lDHlDTlDtlDlDlDlDlDlDlDlDlD lD lD ,lD<lDTlDhlDplDlDlDlDlDlD"lD#lD)lD+lD,lD-lD/lD%lD&lD'lD0 n@l@l@n@ n@&l@n@l l l$Tn$5vo@1!o1l2j@21o2@o3l3 n4n4lD5lD6$lD<$lD?0lD@<lDAHlDBTlDH`lDIlDKlDRlDWlD\lD]lD`lDalDblDe lDl(lDr0lDsHlDwXlDx\lDw`lDzdlD{xlD|lD}lDlDlDlDlDlDlDlDlDlDlDlDlDlDlDlDlD lD0lD4@2Wo@3n@6do@7yo@7 n@89m@8&l@8l@8o9o9l$l4l$xo$xm@o@k@lDlDlDlD(lD4lD@lDLlDllDlDlDlDlDlDlDlDlDlDlDlD lD$lD,lD4lD@@zlDEHlDFHlDGXjPzlDXlDdlDlDlDzlDElDFlDGjzlDlDlDlDlD lD lD lDlDlDlD$lD(lD4lDLlD`lDllDxlDlD lDlD"lD&lD'lD)lD*lD+lD,lD.lD/n@l@mo,o@o@ p@p@l@o(o$&l@ @lIn(lHlXIn$llll$$ld|zd|+pd;|8<GqM4Ni 22-Fsr:5j666G 65ɡxH  R B ֡mI\ v5{.[v$Ee)7Ԥ'{p]־1JI),E{>Yx ,R(<5Fjjy4}@%]s:Un))2/"2_7dA88 ):**/+D+^+y++++MBPQU S;;>O>k>@p 5Vp 6lp 7p 8p 9p :p$E|p@D]\Dp@D k@DqDkDlDElDF lDH$lDIDlDO\lDShlDVlD[lD\lDdlDelDhlDilDplDrlDslDw lD^(lD_4lD`<lDaLlDxP#q@F:q@HJqHYqI{q@Jl lPl$q$}q@~q@~ P\llql qklDlD(lD(lD,lD|lDlDlDlDlDlDlDlDlDlD0lD<lDDlDPlDXlDplDxlDlDlDlDlDlDlDlDlDlDlDlDlD lD(lD0lD@lDDlDLlDdlDtlD|lDlDlDlDlDlDlDlDlD@Wo@l@l@ m@*m@q@q@{q@:q@Jqrr.rl(ll$DPr${r@h\tk@lDlDlD lD@lDXlD dlD lDlDlDlDlDlDlDlDlDԁlDElDFlDG+plDlDlD$lD,lD"4lD#<lD$DlD&PlD(XlD)`lD,dlD-xlD.lD/lD1lD6lD7lD8lD:lD<lD=lD>lDClDDlDFlD@lDGl@[r@]@:q@rrx*n@lllll$Hr$L0p@JrJk@Jr@K nKlDLlDM lDP$lDQDlDR\lDYtlD^lD_lDalDclDdlDflDglDhlDi lDllDm0lDq8lDrTlDsdlDutlDv|lDwlD{lD|lD~lDlDlDlDlDlDlDlDlDlDlD(lD0lD8lD<s@Mn@N:q@PsP(sQ<lD@HlDBPlDCdlDEhlDGtlDIlDJlDKlDLlDNlDPlDNlDSlDVlDWlDXlD[lD\ n@s@[Et0\@Rt@]t@nt@:q@s0(s0~t$@lltllll l$Tld|zd|td;|8<GqM4Ni 2t ld|zd|td;|8<GqM4Ni 2t ld|zd|ud;|8<GqM4Ni 2u ld|zd|8ud;|8<GqM4Ni 2Ju ld|zd|wud;|8<GqM4Ni 2u ld|zd|ud;|8<GqM4Ni 2u ld|zd|ud;|8<GqM4Ni 2u ld|zd|%vd;|8<GqM4Ni 2/v ld|zd|Tvd;|8<GqM4Ni 2^v ld|zd|vd;|8<GqM4Ni 2v ld|zd|vd;|8<GqM4Ni 2v ld|zd|vd;|8<GqM4Ni 2v ld|zd|$wd;|8<GqM4Ni 24w ld|zd|`wd;|8<GqM4Ni 2rw ld|wd|wd;|8<GqM4Ni 2wwwxxx3xllAxRxcxxxx yyMyyyy#zXzzzzllzl {llll!{lll3{>{lJ{lW{{{{|2|\|||||%}Q}}}}}/~lW~lb~s~v~~~ l~I~J~K L"M8ONPdY||H -Fb~lR Fls%92Jbx "#.׀/01"2;3U5n68:Á;ہ<= >$?>@UAnBCDEтFK+NDO]PuQSVe h$k?qZrwuvyτz}#?l\.nBb~l|P%Zʆ9|::RilAl$p|lj@n݉@n @o@ol$Xldԋ/tmp/cc0mpPEi.s/home/scottb/projects/glibc/csu/init.cgcc2_compiled.int:t(0,1)=r(0,1);-2147483648;2147483647;char:t(0,2)=r(0,2);0;255;long int:t(0,3)=r(0,3);-2147483648;2147483647;unsigned int:t(0,4)=r(0,4);0;-1;long unsigned int:t(0,5)=r(0,5);0;-1;long long int:t(0,6)=r(0,1);01000000000000000000000;0777777777777777777777;long long unsigned int:t(0,7)=r(0,1);0000000000000;01777777777777777777777;short int:t(0,8)=r(0,8);-32768;32767;short unsigned int:t(0,9)=r(0,9);0;65535;signed char:t(0,10)=r(0,10);-128;127;unsigned char:t(0,11)=r(0,11);0;255;float:t(0,12)=r(0,1);4;0;double:t(0,13)=r(0,1);8;0;long double:t(0,14)=r(0,1);8;0;complex int:t(0,15)=s8real:(0,1),0,32;imag:(0,1),32,32;;complex float:t(0,16)=r(0,16);4;0;complex double:t(0,17)=r(0,17);8;0;complex long double:t(0,18)=r(0,18);8;0;void:t(0,19)=(0,19)../include/libc-symbols.h../config.h../include/libintl.h../intl/libintl.h../include/features.h../include/sys/cdefs.h../misc/sys/cdefs.h/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/stddef.h../include/locale.h../locale/locale.hlconv:T(11,1)=s48decimal_point:(11,2)=*(0,2),0,32;thousands_sep:(11,2),32,32;\grouping:(11,2),64,32;int_curr_symbol:(11,2),96,32;\currency_symbol:(11,2),128,32;mon_decimal_point:(11,2),160,32;\mon_thousands_sep:(11,2),192,32;mon_grouping:(11,2),224,32;\positive_sign:(11,2),256,32;negative_sign:(11,2),288,32;\int_frac_digits:(0,2),320,8;frac_digits:(0,2),328,8;\p_cs_precedes:(0,2),336,8;p_sep_by_space:(0,2),344,8;\n_cs_precedes:(0,2),352,8;n_sep_by_space:(0,2),360,8;\p_sign_posn:(0,2),368,8;n_sign_posn:(0,2),376,8;;../include/xlocale.h../locale/xlocale.h__locale_struct:T(14,1)=s36__locales:(14,2)=ar(0,0);0;5;(14,3)=*(14,4)=xslocale_data:,0,192;\__ctype_b:(14,5)=*(0,9),192,32;__ctype_tolower:(14,6)=*(0,1),224,32;\__ctype_toupper:(14,6),256,32;;__locale_t:t(14,7)=(14,8)=*(14,1)../libio/libio.h../sysdeps/unix/sysv/linux/_G_config.h../sysdeps/unix/sysv/linux/bits/types.h__u_char:t(17,1)=(0,11)__u_short:t(17,2)=(0,9)__u_int:t(17,3)=(0,4)__u_long:t(17,4)=(0,5)__u_quad_t:t(17,5)=(0,7)__quad_t:t(17,6)=(0,6)__int8_t:t(17,7)=(0,10)__uint8_t:t(17,8)=(0,11)__int16_t:t(17,9)=(0,8)__uint16_t:t(17,10)=(0,9)__int32_t:t(17,11)=(0,1)__uint32_t:t(17,12)=(0,4)__int64_t:t(17,13)=(0,6)__uint64_t:t(17,14)=(0,7)__qaddr_t:t(17,15)=(17,16)=*(17,6)__dev_t:t(17,17)=(17,5)__uid_t:t(17,18)=(17,3)__gid_t:t(17,19)=(17,3)__ino_t:t(17,20)=(17,4)__mode_t:t(17,21)=(17,3)__nlink_t:t(17,22)=(17,3)__off_t:t(17,23)=(0,3)__loff_t:t(17,24)=(17,6)__pid_t:t(17,25)=(0,1)__ssize_t:t(17,26)=(0,1)__rlim_t:t(17,27)=(0,3)__rlim64_t:t(17,28)=(17,6)__id_t:t(17,29)=(17,3)__fsid_t:t(17,30)=(17,31)=s8__val:(17,32)=ar(0,0);0;1;(0,1),0,64;;__daddr_t:t(17,33)=(0,1)__caddr_t:t(17,34)=(11,2)__time_t:t(17,35)=(0,3)__swblk_t:t(17,36)=(0,3)__clock_t:t(17,37)=(0,3)__fd_mask:t(17,38)=(0,5)__fd_set:t(17,39)=(17,40)=s128fds_bits:(17,41)=ar(0,0);0;31;(17,38),0,1024;;__key_t:t(17,42)=(0,1)__ipc_pid_t:t(17,43)=(0,9)__blkcnt_t:t(17,44)=(17,4)__blkcnt64_t:t(17,45)=(17,5)__fsblkcnt_t:t(17,46)=(0,3)__fsblkcnt64_t:t(17,47)=(17,6)__fsfilcnt_t:t(17,48)=(17,4)__fsfilcnt64_t:t(17,49)=(17,5)__ino64_t:t(17,50)=(17,4)__off64_t:t(17,51)=(17,24)__t_scalar_t:t(17,52)=(0,1)__t_uscalar_t:t(17,53)=(0,4)size_t:t(18,1)=(0,4)wchar_t:t(18,2)=(0,3)wint_t:t(18,3)=(0,4)_G_int16_t:t(16,1)=(0,8)_G_int32_t:t(16,2)=(0,1)_G_uint16_t:t(16,3)=(0,9)_G_uint32_t:t(16,4)=(0,4)/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/stdarg.h__gnuc_va_list:t(19,1)=(19,2)=*(0,19)_IO_lock_t:t(15,1)=(0,19)_IO_marker:T(15,2)=s12_next:(15,3)=*(15,2),0,32;_sbuf:(15,4)=*(15,5)=xs_IO_FILE:,32,32;\_pos:(0,1),64,32;;_IO_FILE:T(15,5)=s148_flags:(0,1),0,32;_IO_read_ptr:(11,2),32,32;\_IO_read_end:(11,2),64,32;_IO_read_base:(11,2),96,32;\_IO_write_base:(11,2),128,32;_IO_write_ptr:(11,2),160,32;\_IO_write_end:(11,2),192,32;_IO_buf_base:(11,2),224,32;\_IO_buf_end:(11,2),256,32;_IO_save_base:(11,2),288,32;\_IO_backup_base:(11,2),320,32;_IO_save_end:(11,2),352,32;\_markers:(15,3),384,32;_chain:(15,4),416,32;_fileno:(0,1),448,32;\_blksize:(0,1),480,32;_old_offset:(17,23),512,32;\_cur_column:(0,9),544,16;_vtable_offset:(0,10),560,8;\_shortbuf:(15,6)=ar(0,0);0;0;(0,2),568,8;_lock:(15,7)=*(15,1),576,32;\_offset:(17,51),608,64;_unused2:(15,8)=ar(0,0);0;15;(0,1),672,512;;_IO_FILE:t(15,9)=(15,5)_IO_cookie_io_functions_t:t(15,10)=(15,11)=s16read:(15,12)=*(15,13)=f(17,26),0,32;\write:(15,14)=*(15,15)=f(17,26),32,32;seek:(15,16)=*(15,17)=f(17,23),64,32;\close:(15,18)=*(15,19)=f(0,1),96,32;;_IO_cookie_file:T(15,20)=s172file:(15,5),0,1184;vtable:(15,21)=*(0,19),1184,32;\cookie:(19,2),1216,32;io_functions:(15,10),1248,128;;_IO_stdin_used:G(15,21)/drx1/luigi/sw/netwinder/sdr/linux/../src/bitmaps.c/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/tcl.h/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/stdio.h/usr/include/features.h/usr/include/sys/cdefs.h/usr/include/gnu/stubs.hsize_t:t(7,1)=(0,4)/usr/include/bits/types.h__u_char:t(9,1)=(0,11)__u_short:t(9,2)=(0,9)__u_int:t(9,3)=(0,4)__u_long:t(9,4)=(0,5)__u_quad_t:t(9,5)=(0,7)__quad_t:t(9,6)=(0,6)__int8_t:t(9,7)=(0,10)__uint8_t:t(9,8)=(0,11)__int16_t:t(9,9)=(0,8)__uint16_t:t(9,10)=(0,9)__int32_t:t(9,11)=(0,1)__uint32_t:t(9,12)=(0,4)__int64_t:t(9,13)=(0,6)__uint64_t:t(9,14)=(0,7)__qaddr_t:t(9,15)=(9,16)=*(9,6)__dev_t:t(9,17)=(9,5)__uid_t:t(9,18)=(9,3)__gid_t:t(9,19)=(9,3)__ino_t:t(9,20)=(9,4)__mode_t:t(9,21)=(9,3)__nlink_t:t(9,22)=(9,3)__off_t:t(9,23)=(0,3)__loff_t:t(9,24)=(9,6)__pid_t:t(9,25)=(0,1)__ssize_t:t(9,26)=(0,1)__rlim_t:t(9,27)=(0,3)__rlim64_t:t(9,28)=(9,6)__id_t:t(9,29)=(9,3)__fsid_t:t(9,30)=(9,31)=s8__val:(9,32)=ar(0,0);0;1;(0,1),0,64;;__daddr_t:t(9,33)=(0,1)__caddr_t:t(9,34)=(9,35)=*(0,2)__time_t:t(9,36)=(0,3)__swblk_t:t(9,37)=(0,3)__clock_t:t(9,38)=(0,3)__fd_mask:t(9,39)=(0,5)__fd_set:t(9,40)=(9,41)=s128fds_bits:(9,42)=ar(0,0);0;31;(9,39),0,1024;;__key_t:t(9,43)=(0,1)__ipc_pid_t:t(9,44)=(0,9)__blkcnt_t:t(9,45)=(9,4)__blkcnt64_t:t(9,46)=(9,5)__fsblkcnt_t:t(9,47)=(0,3)__fsblkcnt64_t:t(9,48)=(9,6)__fsfilcnt_t:t(9,49)=(9,4)__fsfilcnt64_t:t(9,50)=(9,5)__ino64_t:t(9,51)=(9,4)__off64_t:t(9,52)=(9,24)__t_scalar_t:t(9,53)=(0,1)__t_uscalar_t:t(9,54)=(0,4)FILE:t(2,1)=(2,2)=xs_IO_FILE:/usr/include/libio.h/usr/include/_G_config.hwchar_t:t(12,1)=(0,3)wint_t:t(12,2)=(0,4)_G_int16_t:t(11,1)=(0,8)_G_int32_t:t(11,2)=(0,1)_G_uint16_t:t(11,3)=(0,9)_G_uint32_t:t(11,4)=(0,4)_IO_lock_t:t(10,1)=(0,19)_IO_marker:T(10,2)=s12_next:(10,3)=*(10,2),0,32;_sbuf:(10,4)=*(2,2),32,32;\_IO_FILE:T(2,2)=s148_flags:(0,1),0,32;_IO_read_ptr:(9,35),32,32;\_IO_read_end:(9,35),64,32;_IO_read_base:(9,35),96,32;\_IO_write_base:(9,35),128,32;_IO_write_ptr:(9,35),160,32;\_IO_write_end:(9,35),192,32;_IO_buf_base:(9,35),224,32;\_IO_buf_end:(9,35),256,32;_IO_save_base:(9,35),288,32;\_IO_backup_base:(9,35),320,32;_IO_save_end:(9,35),352,32;\_markers:(10,3),384,32;_chain:(10,4),416,32;_fileno:(0,1),448,32;\_blksize:(0,1),480,32;_old_offset:(9,23),512,32;\_shortbuf:(10,5)=ar(0,0);0;0;(0,2),568,8;_lock:(10,6)=*(10,1),576,32;\_offset:(9,52),608,64;_unused2:(10,7)=ar(0,0);0;15;(0,1),672,512;;_IO_FILE:t(10,8)=(2,2)_IO_cookie_io_functions_t:t(10,9)=(10,10)=s16read:(10,11)=*(10,12)=f(9,26),0,32;\write:(10,13)=*(10,14)=f(9,26),32,32;seek:(10,15)=*(10,16)=f(9,23),64,32;\close:(10,17)=*(10,18)=f(0,1),96,32;;_IO_cookie_file:T(10,19)=s172file:(2,2),0,1184;vtable:(10,20)=*(0,19),1184,32;\cookie:(8,2),1216,32;io_functions:(10,9),1248,128;;fpos_t:t(2,3)=(9,23)/usr/include/bits/stdio_lim.hClientData:t(1,1)=(8,2)Tcl_Interp:T(1,2)=s12result:(9,35),0,32;freeProc:(1,3)=*(1,4)=f(0,19),32,32;\errorLine:(0,1),64,32;;Tcl_Interp:t(1,5)=(1,2)Tcl_AsyncHandler:t(1,6)=(1,7)=*(1,8)=xsTcl_AsyncHandler_:Tcl_Channel:t(1,9)=(1,10)=*(1,11)=xsTcl_Channel_:Tcl_Command:t(1,12)=(1,13)=*(1,14)=xsTcl_Command_:Tcl_Event:t(1,15)=(1,16)=xsTcl_Event:Tcl_Pid:t(1,17)=(1,18)=*(1,19)=xsTcl_Pid_:Tcl_RegExp:t(1,20)=(1,21)=*(1,22)=xsTcl_RegExp_:Tcl_TimerToken:t(1,23)=(1,24)=*(1,25)=xsTcl_TimerToken_:Tcl_Trace:t(1,26)=(1,27)=*(1,28)=xsTcl_Trace_:Tcl_Var:t(1,29)=(1,30)=*(1,31)=xsTcl_Var_: :T(1,32)=eTCL_INT:0,TCL_DOUBLE:1,TCL_EITHER:2,;Tcl_ValueType:t(1,33)=(1,32)Tcl_Value:T(1,34)=s16type:(1,33),0,32;intValue:(0,3),32,32;\doubleValue:(0,13),64,64;;Tcl_Value:t(1,35)=(1,34)Tcl_AppInitProc:t(1,36)=(1,37)=f(0,1)Tcl_AsyncProc:t(1,38)=(1,39)=f(0,1)Tcl_ChannelProc:t(1,40)=(1,41)=f(0,19)Tcl_CloseProc:t(1,42)=(1,43)=f(0,19)Tcl_CmdDeleteProc:t(1,44)=(1,43)Tcl_CmdProc:t(1,45)=(1,46)=f(0,1)Tcl_CmdTraceProc:t(1,47)=(1,48)=f(0,19)Tcl_DupInternalRepProc:t(1,49)=(1,50)=f(0,19)Tcl_EventProc:t(1,51)=(1,52)=f(0,1)Tcl_EventCheckProc:t(1,53)=(1,41)Tcl_EventDeleteProc:t(1,54)=(1,55)=f(0,1)Tcl_EventSetupProc:t(1,56)=(1,41)Tcl_ExitProc:t(1,57)=(1,43)Tcl_FileProc:t(1,58)=(1,41)Tcl_FileFreeProc:t(1,59)=(1,43)Tcl_FreeInternalRepProc:t(1,60)=(1,61)=f(0,19)Tcl_FreeProc:t(1,62)=(1,4)Tcl_IdleProc:t(1,63)=(1,43)Tcl_InterpDeleteProc:t(1,64)=(1,65)=f(0,19)Tcl_MathProc:t(1,66)=(1,67)=f(0,1)Tcl_NamespaceDeleteProc:t(1,68)=(1,43)Tcl_ObjCmdProc:t(1,69)=(1,70)=f(0,1)Tcl_PackageInitProc:t(1,71)=(1,37)Tcl_TcpAcceptProc:t(1,72)=(1,73)=f(0,19)Tcl_TimerProc:t(1,74)=(1,43)Tcl_SetFromAnyProc:t(1,75)=(1,76)=f(0,1)Tcl_UpdateStringProc:t(1,77)=(1,61)Tcl_VarTraceProc:t(1,78)=(1,79)=f(9,35)Tcl_ObjType:T(1,80)=s20name:(9,35),0,32;freeIntRepProc:(1,81)=*(1,60),32,32;\dupIntRepProc:(1,82)=*(1,49),64,32;updateStringProc:(1,83)=*(1,77),96,32;\setFromAnyProc:(1,84)=*(1,75),128,32;;Tcl_ObjType:t(1,85)=(1,80)Tcl_Obj:T(1,86)=s24refCount:(0,1),0,32;bytes:(9,35),32,32;\length:(0,1),64,32;typePtr:(1,87)=*(1,85),96,32;\internalRep:(1,88)=u8longValue:(0,3),0,32;doubleValue:(0,13),0,64;\otherValuePtr:(8,2),0,32;twoPtrValue:(1,89)=s8ptr1:(8,2),0,32;\ptr2:(8,2),32,32;;,0,64;;,128,64;;Tcl_Obj:t(1,90)=(1,86)Tcl_Namespace:T(1,91)=s20name:(9,35),0,32;fullName:(9,35),32,32;\clientData:(1,1),64,32;deleteProc:(1,92)=*(1,68),96,32;\parentPtr:(1,93)=*(1,91),128,32;;Tcl_Namespace:t(1,94)=(1,91)Tcl_CallFrame:T(1,95)=s44nsPtr:(1,96)=*(1,94),0,32;dummy1:(0,1),32,32;\dummy2:(0,1),64,32;dummy3:(9,35),96,32;dummy4:(9,35),128,32;\dummy5:(9,35),160,32;dummy6:(0,1),192,32;dummy7:(9,35),224,32;\dummy8:(9,35),256,32;dummy9:(0,1),288,32;dummy10:(9,35),320,32;;Tcl_CallFrame:t(1,97)=(1,95)Tcl_CmdInfo:T(1,98)=s32isNativeObjectProc:(0,1),0,32;\objProc:(1,99)=*(1,69),32,32;objClientData:(1,1),64,32;\proc:(1,100)=*(1,45),96,32;clientData:(1,1),128,32;\deleteProc:(1,101)=*(1,44),160,32;deleteData:(1,1),192,32;\namespacePtr:(1,96),224,32;;Tcl_CmdInfo:t(1,102)=(1,98)Tcl_DString:T(1,103)=s212string:(9,35),0,32;length:(0,1),32,32;\spaceAvl:(0,1),64,32;staticSpace:(1,104)=ar(0,0);0;199;(0,2),96,1600;;Tcl_DString:t(1,105)=(1,103)Tcl_HashEntry:T(1,106)=s20nextPtr:(1,107)=*(1,106),0,32;\tablePtr:(1,108)=*(1,109)=xsTcl_HashTable:,32,32;bucketPtr:(1,110)=*(1,107),64,32;\clientData:(1,1),96,32;key:(1,111)=u4oneWordValue:(9,35),0,32;\words:(1,112)=ar(0,0);0;0;(0,1),0,32;string:(1,113)=ar(0,0);0;3;(0,2),0,32;;,128,32;;Tcl_HashEntry:t(1,114)=(1,106)Tcl_HashTable:T(1,109)=s52buckets:(1,115)=*(1,116)=*(1,114),0,32;\staticBuckets:(1,117)=ar(0,0);0;3;(1,116),32,128;numBuckets:(0,1),160,32;\numEntries:(0,1),192,32;rebuildSize:(0,1),224,32;\downShift:(0,1),256,32;mask:(0,1),288,32;keyType:(0,1),320,32;\findProc:(1,118)=*(1,119)=f(1,116),352,32;createProc:(1,120)=*(1,121)=f(1,116),384,32;;Tcl_HashTable:t(1,122)=(1,109)Tcl_HashSearch:T(1,123)=s12tablePtr:(1,124)=*(1,122),0,32;\nextIndex:(0,1),32,32;nextEntryPtr:(1,116),64,32;;Tcl_HashSearch:t(1,125)=(1,123)Tcl_Event:T(1,16)=s8proc:(1,126)=*(1,51),0,32;nextPtr:(1,127)=*(1,16),32,32;; :T(1,128)=eTCL_QUEUE_TAIL:0,TCL_QUEUE_HEAD:1,TCL_QUEUE_MARK:2,;Tcl_QueuePosition:t(1,129)=(1,128)Tcl_Time:T(1,130)=s8sec:(0,3),0,32;usec:(0,3),32,32;;Tcl_Time:t(1,131)=(1,130)Tcl_DriverBlockModeProc:t(1,132)=(1,133)=f(0,1)Tcl_DriverCloseProc:t(1,134)=(1,135)=f(0,1)Tcl_DriverInputProc:t(1,136)=(1,137)=f(0,1)Tcl_DriverOutputProc:t(1,138)=(1,137)Tcl_DriverSeekProc:t(1,139)=(1,140)=f(0,1)Tcl_DriverSetOptionProc:t(1,141)=(1,142)=f(0,1)Tcl_DriverGetOptionProc:t(1,143)=(1,144)=f(0,1)Tcl_DriverWatchProc:t(1,145)=(1,41)Tcl_DriverGetHandleProc:t(1,146)=(1,147)=f(0,1)Tcl_EolTranslation:T(1,148)=eTCL_TRANSLATE_AUTO:0,TCL_TRANSLATE_CR:1,\TCL_TRANSLATE_LF:2,TCL_TRANSLATE_CRLF:3,;Tcl_EolTranslation:t(1,149)=(1,148)Tcl_ChannelType:T(1,150)=s40typeName:(9,35),0,32;blockModeProc:(1,151)=*(1,132),32,32;\closeProc:(1,152)=*(1,134),64,32;inputProc:(1,153)=*(1,136),96,32;\outputProc:(1,154)=*(1,138),128,32;seekProc:(1,155)=*(1,139),160,32;\setOptionProc:(1,156)=*(1,141),192,32;getOptionProc:(1,157)=*(1,143),224,32;\watchProc:(1,158)=*(1,145),256,32;getHandleProc:(1,159)=*(1,146),288,32;;Tcl_ChannelType:t(1,160)=(1,150)Tcl_PathType:T(1,161)=eTCL_PATH_ABSOLUTE:0,TCL_PATH_RELATIVE:1,\TCL_PATH_VOLUME_RELATIVE:2,;Tcl_PathType:t(1,162)=(1,161)/usr/include/tk.h/usr/include/X11/Xlib.h/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/sys/types.hu_char:t(17,1)=(9,1)u_short:t(17,2)=(9,2)u_int:t(17,3)=(9,3)u_long:t(17,4)=(9,4)quad_t:t(17,5)=(9,6)u_quad_t:t(17,6)=(9,5)fsid_t:t(17,7)=(9,30)loff_t:t(17,8)=(9,24)ino_t:t(17,9)=(9,20)dev_t:t(17,10)=(9,17)gid_t:t(17,11)=(9,19)mode_t:t(17,12)=(9,21)nlink_t:t(17,13)=(9,22)uid_t:t(17,14)=(9,18)off_t:t(17,15)=(9,23)pid_t:t(17,16)=(9,25)id_t:t(17,17)=(9,29)ssize_t:t(17,18)=(9,26)daddr_t:t(17,19)=(9,33)caddr_t:t(17,20)=(9,34)key_t:t(17,21)=(9,43)/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/time.htime_t:t(18,1)=(9,36)ulong:t(17,22)=(0,5)ushort:t(17,23)=(0,9)uint:t(17,24)=(0,4)int8_t:t(17,25)=(0,10)int16_t:t(17,26)=(0,8)int32_t:t(17,27)=(0,1)int64_t:t(17,28)=(0,6)u_int8_t:t(17,29)=(0,11)u_int16_t:t(17,30)=(0,9)u_int32_t:t(17,31)=(0,4)u_int64_t:t(17,32)=(0,7)register_t:t(17,33)=(0,1)/usr/include/endian.h/usr/include/bits/endian.h/usr/include/sys/select.h/usr/include/bits/select.htimespec:T(24,1)=s8tv_sec:(0,3),0,32;tv_nsec:(0,3),32,32;;fd_mask:t(22,1)=(9,39)fd_set:t(22,2)=(9,40)blkcnt_t:t(17,34)=(9,45)fsblkcnt_t:t(17,35)=(9,47)fsfilcnt_t:t(17,36)=(9,49)/usr/include/X11/X.hXID:t(25,1)=(0,5)Mask:t(25,2)=(0,5)Atom:t(25,3)=(0,5)VisualID:t(25,4)=(0,5)Time:t(25,5)=(0,5)Window:t(25,6)=(25,1)Drawable:t(25,7)=(25,1)Font:t(25,8)=(25,1)Pixmap:t(25,9)=(25,1)Cursor:t(25,10)=(25,1)Colormap:t(25,11)=(25,1)GContext:t(25,12)=(25,1)KeySym:t(25,13)=(25,1)KeyCode:t(25,14)=(0,11)/usr/include/X11/Xfuncproto.h/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/X11/Xosdefs.hptrdiff_t:t(28,1)=(0,1)XPointer:t(16,1)=(9,35)_XExtData:T(16,2)=s16number:(0,1),0,32;next:(16,3)=*(16,2),32,32;\free_private:(16,4)=*(16,5)=f(0,1),64,32;private_data:(16,1),96,32;;XExtData:t(16,6)=(16,2)XExtCodes:t(16,7)=(16,8)=s16extension:(0,1),0,32;major_opcode:(0,1),32,32;\first_event:(0,1),64,32;first_error:(0,1),96,32;;XPixmapFormatValues:t(16,9)=(16,10)=s12depth:(0,1),0,32;\bits_per_pixel:(0,1),32,32;scanline_pad:(0,1),64,32;;XGCValues:t(16,11)=(16,12)=s92function:(0,1),0,32;plane_mask:(0,5),32,32;\foreground:(0,5),64,32;background:(0,5),96,32;\line_width:(0,1),128,32;line_style:(0,1),160,32;\cap_style:(0,1),192,32;join_style:(0,1),224,32;\fill_style:(0,1),256,32;fill_rule:(0,1),288,32;\arc_mode:(0,1),320,32;tile:(25,9),352,32;stipple:(25,9),384,32;\ts_x_origin:(0,1),416,32;ts_y_origin:(0,1),448,32;\font:(25,8),480,32;subwindow_mode:(0,1),512,32;\graphics_exposures:(0,1),544,32;clip_x_origin:(0,1),576,32;\clip_y_origin:(0,1),608,32;clip_mask:(25,9),640,32;\dash_offset:(0,1),672,32;dashes:(0,2),704,8;;GC:t(16,13)=(16,14)=*(16,15)=xs_XGC:Visual:t(16,16)=(16,17)=s32ext_data:(16,18)=*(16,6),0,32;\visualid:(25,4),32,32;class:(0,1),64,32;red_mask:(0,5),96,32;\green_mask:(0,5),128,32;blue_mask:(0,5),160,32;\bits_per_rgb:(0,1),192,32;map_entries:(0,1),224,32;;Depth:t(16,19)=(16,20)=s12depth:(0,1),0,32;nvisuals:(0,1),32,32;\visuals:(16,21)=*(16,16),64,32;;Screen:t(16,22)=(16,23)=s80ext_data:(16,18),0,32;display:(16,24)=*(16,25)=xs_XDisplay:,32,32;\root:(25,6),64,32;width:(0,1),96,32;height:(0,1),128,32;\mwidth:(0,1),160,32;mheight:(0,1),192,32;ndepths:(0,1),224,32;\depths:(16,26)=*(16,19),256,32;root_depth:(0,1),288,32;\root_visual:(16,21),320,32;default_gc:(16,13),352,32;\cmap:(25,11),384,32;white_pixel:(0,5),416,32;black_pixel:(0,5),448,32;\max_maps:(0,1),480,32;min_maps:(0,1),512,32;backing_store:(0,1),544,32;\save_unders:(0,1),576,32;root_input_mask:(0,3),608,32;;ScreenFormat:t(16,27)=(16,28)=s16ext_data:(16,18),0,32;\depth:(0,1),32,32;bits_per_pixel:(0,1),64,32;\scanline_pad:(0,1),96,32;;XSetWindowAttributes:t(16,29)=(16,30)=s60background_pixmap:(25,9),0,32;\background_pixel:(0,5),32,32;border_pixmap:(25,9),64,32;\border_pixel:(0,5),96,32;bit_gravity:(0,1),128,32;\win_gravity:(0,1),160,32;backing_store:(0,1),192,32;\backing_planes:(0,5),224,32;backing_pixel:(0,5),256,32;\save_under:(0,1),288,32;event_mask:(0,3),320,32;\do_not_propagate_mask:(0,3),352,32;override_redirect:(0,1),384,32;\colormap:(25,11),416,32;cursor:(25,10),448,32;;XWindowAttributes:t(16,31)=(16,32)=s92x:(0,1),0,32;y:(0,1),32,32;\width:(0,1),64,32;height:(0,1),96,32;border_width:(0,1),128,32;\depth:(0,1),160,32;visual:(16,21),192,32;root:(25,6),224,32;\class:(0,1),256,32;bit_gravity:(0,1),288,32;win_gravity:(0,1),320,32;\backing_store:(0,1),352,32;backing_planes:(0,5),384,32;\backing_pixel:(0,5),416,32;save_under:(0,1),448,32;\colormap:(25,11),480,32;map_installed:(0,1),512,32;\map_state:(0,1),544,32;all_event_masks:(0,3),576,32;\your_event_mask:(0,3),608,32;do_not_propagate_mask:(0,3),640,32;\override_redirect:(0,1),672,32;screen:(16,33)=*(16,22),704,32;;XHostAddress:t(16,34)=(16,35)=s12family:(0,1),0,32;length:(0,1),32,32;\address:(9,35),64,32;;funcs:T(16,36)=s24create_image:(16,37)=*(16,38)=f(16,39)=*(16,40)=xs_XImage:,0,32;\destroy_image:(16,41)=*(16,42)=f(0,1),32,32;get_pixel:(16,43)=*(16,44)=f(0,5),64,32;\put_pixel:(16,45)=*(16,46)=f(0,1),96,32;sub_image:(16,47)=*(16,48)=f(16,39),128,32;\add_pixel:(16,49)=*(16,50)=f(0,1),160,32;;_XImage:T(16,40)=s88width:(0,1),0,32;height:(0,1),32,32;\xoffset:(0,1),64,32;format:(0,1),96,32;data:(9,35),128,32;\byte_order:(0,1),160,32;bitmap_unit:(0,1),192,32;\bitmap_bit_order:(0,1),224,32;bitmap_pad:(0,1),256,32;\depth:(0,1),288,32;bytes_per_line:(0,1),320,32;\bits_per_pixel:(0,1),352,32;red_mask:(0,5),384,32;\green_mask:(0,5),416,32;blue_mask:(0,5),448,32;\obdata:(16,1),480,32;f:(16,36),512,192;;XImage:t(16,51)=(16,40)XWindowChanges:t(16,52)=(16,53)=s28x:(0,1),0,32;y:(0,1),32,32;\sibling:(25,6),160,32;stack_mode:(0,1),192,32;;XColor:t(16,54)=(16,55)=s12pixel:(0,5),0,32;red:(0,9),32,16;\green:(0,9),48,16;blue:(0,9),64,16;flags:(0,2),80,8;\pad:(0,2),88,8;;XSegment:t(16,56)=(16,57)=s8x1:(0,8),0,16;y1:(0,8),16,16;\x2:(0,8),32,16;y2:(0,8),48,16;;XPoint:t(16,58)=(16,59)=s4x:(0,8),0,16;y:(0,8),16,16;;XRectangle:t(16,60)=(16,61)=s8x:(0,8),0,16;y:(0,8),16,16;\width:(0,9),32,16;height:(0,9),48,16;;XArc:t(16,62)=(16,63)=s12x:(0,8),0,16;y:(0,8),16,16;\width:(0,9),32,16;height:(0,9),48,16;angle1:(0,8),64,16;\angle2:(0,8),80,16;;XKeyboardControl:t(16,64)=(16,65)=s32key_click_percent:(0,1),0,32;\bell_percent:(0,1),32,32;bell_pitch:(0,1),64,32;\bell_duration:(0,1),96,32;led:(0,1),128,32;led_mode:(0,1),160,32;\key:(0,1),192,32;auto_repeat_mode:(0,1),224,32;;XKeyboardState:t(16,66)=(16,67)=s56key_click_percent:(0,1),0,32;\bell_percent:(0,1),32,32;bell_pitch:(0,4),64,32;\bell_duration:(0,4),96,32;led_mask:(0,5),128,32;\global_auto_repeat:(0,1),160,32;auto_repeats:(16,68)=ar(0,0);0;31;(0,2),192,256;;XTimeCoord:t(16,69)=(16,70)=s8time:(25,5),0,32;x:(0,8),32,16;\y:(0,8),48,16;;XModifierKeymap:t(16,71)=(16,72)=s8max_keypermod:(0,1),0,32;\modifiermap:(16,73)=*(25,14),32,32;;Display:t(16,74)=(16,25)_XPrivDisplay:t(16,75)=(16,76)=*(16,77)=s176ext_data:(16,18),0,32;\private1:(16,78)=*(16,79)=xs_XPrivate:,32,32;fd:(0,1),64,32;\private2:(0,1),96,32;proto_major_version:(0,1),128,32;\proto_minor_version:(0,1),160,32;vendor:(9,35),192,32;\private3:(25,1),224,32;private4:(25,1),256,32;private5:(25,1),288,32;\private6:(0,1),320,32;resource_alloc:(16,80)=*(16,81)=f(25,1),352,32;\byte_order:(0,1),384,32;bitmap_unit:(0,1),416,32;\bitmap_pad:(0,1),448,32;bitmap_bit_order:(0,1),480,32;\nformats:(0,1),512,32;pixmap_format:(16,82)=*(16,27),544,32;\private8:(0,1),576,32;release:(0,1),608,32;private9:(16,78),640,32;\private10:(16,78),672,32;qlen:(0,1),704,32;last_request_read:(0,5),736,32;\request:(0,5),768,32;private11:(16,1),800,32;private12:(16,1),832,32;\private13:(16,1),864,32;private14:(16,1),896,32;\max_request_size:(0,4),928,32;db:(16,83)=*(16,84)=xs_XrmHashBucketRec:,960,32;\private15:(16,85)=*(16,86)=f(0,1),992,32;display_name:(9,35),1024,32;\default_screen:(0,1),1056,32;nscreens:(0,1),1088,32;\screens:(16,33),1120,32;motion_buffer:(0,5),1152,32;\private16:(0,5),1184,32;min_keycode:(0,1),1216,32;\max_keycode:(0,1),1248,32;private17:(16,1),1280,32;\private18:(16,1),1312,32;private19:(0,1),1344,32;\xdefaults:(9,35),1376,32;;XKeyEvent:t(16,87)=(16,88)=s60type:(0,1),0,32;serial:(0,5),32,32;\send_event:(0,1),64,32;display:(16,89)=*(16,74),96,32;\window:(25,6),128,32;root:(25,6),160,32;subwindow:(25,6),192,32;\time:(25,5),224,32;x:(0,1),256,32;y:(0,1),288,32;\x_root:(0,1),320,32;y_root:(0,1),352,32;state:(0,4),384,32;\keycode:(0,4),416,32;same_screen:(0,1),448,32;;XKeyPressedEvent:t(16,90)=(16,87)XKeyReleasedEvent:t(16,91)=(16,87)XButtonEvent:t(16,92)=(16,93)=s60type:(0,1),0,32;serial:(0,5),32,32;\send_event:(0,1),64,32;display:(16,89),96,32;\button:(0,4),416,32;same_screen:(0,1),448,32;;XButtonPressedEvent:t(16,94)=(16,92)XButtonReleasedEvent:t(16,95)=(16,92)XMotionEvent:t(16,96)=(16,97)=s60type:(0,1),0,32;serial:(0,5),32,32;\is_hint:(0,2),416,8;same_screen:(0,1),448,32;;XPointerMovedEvent:t(16,98)=(16,96)XCrossingEvent:t(16,99)=(16,100)=s68type:(0,1),0,32;serial:(0,5),32,32;\x_root:(0,1),320,32;y_root:(0,1),352,32;mode:(0,1),384,32;\detail:(0,1),416,32;same_screen:(0,1),448,32;\focus:(0,1),480,32;state:(0,4),512,32;;XEnterWindowEvent:t(16,101)=(16,99)XLeaveWindowEvent:t(16,102)=(16,99)XFocusChangeEvent:t(16,103)=(16,104)=s28type:(0,1),0,32;\serial:(0,5),32,32;send_event:(0,1),64,32;display:(16,89),96,32;\window:(25,6),128,32;mode:(0,1),160,32;detail:(0,1),192,32;;XFocusInEvent:t(16,105)=(16,103)XFocusOutEvent:t(16,106)=(16,103)XKeymapEvent:t(16,107)=(16,108)=s52type:(0,1),0,32;serial:(0,5),32,32;\window:(25,6),128,32;key_vector:(16,68),160,256;;XExposeEvent:t(16,109)=(16,110)=s40type:(0,1),0,32;serial:(0,5),32,32;\window:(25,6),128,32;x:(0,1),160,32;y:(0,1),192,32;\width:(0,1),224,32;height:(0,1),256,32;count:(0,1),288,32;;XGraphicsExposeEvent:t(16,111)=(16,112)=s48type:(0,1),0,32;\drawable:(25,7),128,32;x:(0,1),160,32;y:(0,1),192,32;\width:(0,1),224,32;height:(0,1),256,32;count:(0,1),288,32;\major_code:(0,1),320,32;minor_code:(0,1),352,32;;XNoExposeEvent:t(16,113)=(16,114)=s28type:(0,1),0,32;serial:(0,5),32,32;\drawable:(25,7),128,32;major_code:(0,1),160,32;\minor_code:(0,1),192,32;;XVisibilityEvent:t(16,115)=(16,116)=s24type:(0,1),0,32;\window:(25,6),128,32;state:(0,1),160,32;;XCreateWindowEvent:t(16,117)=(16,118)=s48type:(0,1),0,32;\parent:(25,6),128,32;window:(25,6),160,32;x:(0,1),192,32;\y:(0,1),224,32;width:(0,1),256,32;height:(0,1),288,32;\border_width:(0,1),320,32;override_redirect:(0,1),352,32;;XDestroyWindowEvent:t(16,119)=(16,120)=s24type:(0,1),0,32;\event:(25,6),128,32;window:(25,6),160,32;;XUnmapEvent:t(16,121)=(16,122)=s28type:(0,1),0,32;serial:(0,5),32,32;\event:(25,6),128,32;window:(25,6),160,32;from_configure:(0,1),192,32;;XMapEvent:t(16,123)=(16,124)=s28type:(0,1),0,32;serial:(0,5),32,32;\event:(25,6),128,32;window:(25,6),160,32;override_redirect:(0,1),192,32;;XMapRequestEvent:t(16,125)=(16,126)=s24type:(0,1),0,32;\parent:(25,6),128,32;window:(25,6),160,32;;XReparentEvent:t(16,127)=(16,128)=s40type:(0,1),0,32;serial:(0,5),32,32;\event:(25,6),128,32;window:(25,6),160,32;parent:(25,6),192,32;\x:(0,1),224,32;y:(0,1),256,32;override_redirect:(0,1),288,32;;XConfigureEvent:t(16,129)=(16,130)=s52type:(0,1),0,32;serial:(0,5),32,32;\event:(25,6),128,32;window:(25,6),160,32;x:(0,1),192,32;\border_width:(0,1),320,32;above:(25,6),352,32;\override_redirect:(0,1),384,32;;XGravityEvent:t(16,131)=(16,132)=s32type:(0,1),0,32;serial:(0,5),32,32;\y:(0,1),224,32;;XResizeRequestEvent:t(16,133)=(16,134)=s28type:(0,1),0,32;\window:(25,6),128,32;width:(0,1),160,32;height:(0,1),192,32;;XConfigureRequestEvent:t(16,135)=(16,136)=s56type:(0,1),0,32;\detail:(0,1),384,32;value_mask:(0,5),416,32;;XCirculateEvent:t(16,137)=(16,138)=s28type:(0,1),0,32;serial:(0,5),32,32;\event:(25,6),128,32;window:(25,6),160,32;place:(0,1),192,32;;XCirculateRequestEvent:t(16,139)=(16,140)=s28type:(0,1),0,32;\parent:(25,6),128,32;window:(25,6),160,32;place:(0,1),192,32;;XPropertyEvent:t(16,141)=(16,142)=s32type:(0,1),0,32;serial:(0,5),32,32;\window:(25,6),128,32;atom:(25,3),160,32;time:(25,5),192,32;\state:(0,1),224,32;;XSelectionClearEvent:t(16,143)=(16,144)=s28type:(0,1),0,32;\window:(25,6),128,32;selection:(25,3),160,32;time:(25,5),192,32;;XSelectionRequestEvent:t(16,145)=(16,146)=s40type:(0,1),0,32;\owner:(25,6),128,32;requestor:(25,6),160,32;selection:(25,3),192,32;\target:(25,3),224,32;property:(25,3),256,32;time:(25,5),288,32;;XSelectionEvent:t(16,147)=(16,148)=s36type:(0,1),0,32;serial:(0,5),32,32;\requestor:(25,6),128,32;selection:(25,3),160,32;\target:(25,3),192,32;property:(25,3),224,32;time:(25,5),256,32;;XColormapEvent:t(16,149)=(16,150)=s32type:(0,1),0,32;serial:(0,5),32,32;\window:(25,6),128,32;colormap:(25,11),160,32;new:(0,1),192,32;\XClientMessageEvent:t(16,151)=(16,152)=s48type:(0,1),0,32;\window:(25,6),128,32;message_type:(25,3),160,32;\format:(0,1),192,32;data:(16,153)=u20b:(16,154)=ar(0,0);0;19;(0,2),0,160;\s:(16,155)=ar(0,0);0;9;(0,8),0,160;l:(16,156)=ar(0,0);0;4;(0,3),0,160;;,224,160;;XMappingEvent:t(16,157)=(16,158)=s32type:(0,1),0,32;serial:(0,5),32,32;\window:(25,6),128,32;request:(0,1),160,32;first_keycode:(0,1),192,32;\count:(0,1),224,32;;XErrorEvent:t(16,159)=(16,160)=s20type:(0,1),0,32;display:(16,89),32,32;\resourceid:(25,1),64,32;serial:(0,5),96,32;error_code:(0,11),128,8;\request_code:(0,11),136,8;minor_code:(0,11),144,8;;XAnyEvent:t(16,161)=(16,162)=s20type:(0,1),0,32;serial:(0,5),32,32;\window:(25,6),128,32;;_XEvent:T(16,163)=u96type:(0,1),0,32;xany:(16,161),0,160;\xkey:(16,87),0,480;xbutton:(16,92),0,480;xmotion:(16,96),0,480;\xcrossing:(16,99),0,544;xfocus:(16,103),0,224;xexpose:(16,109),0,320;\xgraphicsexpose:(16,111),0,384;xnoexpose:(16,113),0,224;\xvisibility:(16,115),0,192;xcreatewindow:(16,117),0,384;\xdestroywindow:(16,119),0,192;xunmap:(16,121),0,224;\xmap:(16,123),0,224;xmaprequest:(16,125),0,192;xreparent:(16,127),0,320;\xconfigure:(16,129),0,416;xgravity:(16,131),0,256;\xresizerequest:(16,133),0,224;xconfigurerequest:(16,135),0,448;\xcirculate:(16,137),0,224;xcirculaterequest:(16,139),0,224;\xproperty:(16,141),0,256;xselectionclear:(16,143),0,224;\xselectionrequest:(16,145),0,320;xselection:(16,147),0,288;\xcolormap:(16,149),0,256;xclient:(16,151),0,384;xmapping:(16,157),0,256;\xerror:(16,159),0,160;xkeymap:(16,107),0,416;pad:(16,164)=ar(0,0);0;23;(0,3),0,768;;XEvent:t(16,165)=(16,163)XCharStruct:t(16,166)=(16,167)=s12lbearing:(0,8),0,16;rbearing:(0,8),16,16;\width:(0,8),32,16;ascent:(0,8),48,16;descent:(0,8),64,16;\attributes:(0,9),80,16;;XFontProp:t(16,168)=(16,169)=s8name:(25,3),0,32;card32:(0,5),32,32;;XFontStruct:t(16,170)=(16,171)=s80ext_data:(16,18),0,32;fid:(25,8),32,32;\direction:(0,4),64,32;min_char_or_byte2:(0,4),96,32;\max_char_or_byte2:(0,4),128,32;min_byte1:(0,4),160,32;\max_byte1:(0,4),192,32;all_chars_exist:(0,1),224,32;\default_char:(0,4),256,32;n_properties:(0,1),288,32;\properties:(16,172)=*(16,168),320,32;min_bounds:(16,166),352,96;\max_bounds:(16,166),448,96;per_char:(16,173)=*(16,166),544,32;\ascent:(0,1),576,32;descent:(0,1),608,32;;XTextItem:t(16,174)=(16,175)=s16chars:(9,35),0,32;nchars:(0,1),32,32;\delta:(0,1),64,32;font:(25,8),96,32;;XChar2b:t(16,176)=(16,177)=s4byte1:(0,11),0,8;byte2:(0,11),8,8;;XTextItem16:t(16,178)=(16,179)=s16chars:(16,180)=*(16,176),0,32;\nchars:(0,1),32,32;delta:(0,1),64,32;font:(25,8),96,32;;XEDataObject:t(16,181)=(16,182)=u4display:(16,89),0,32;gc:(16,13),0,32;\visual:(16,21),0,32;screen:(16,33),0,32;pixmap_format:(16,82),0,32;\font:(16,183)=*(16,170),0,32;;XFontSetExtents:t(16,184)=(16,185)=s16max_ink_extent:(16,60),0,64;\max_logical_extent:(16,60),64,64;;XOM:t(16,186)=(16,187)=*(16,188)=xs_XOM:XOC:t(16,189)=(16,190)=*(16,191)=xs_XOC:XFontSet:t(16,192)=(16,190)XmbTextItem:t(16,193)=(16,194)=s16chars:(9,35),0,32;nchars:(0,1),32,32;\delta:(0,1),64,32;font_set:(16,192),96,32;;XwcTextItem:t(16,195)=(16,196)=s16chars:(16,197)=*(12,1),0,32;\nchars:(0,1),32,32;delta:(0,1),64,32;font_set:(16,192),96,32;;XOMCharSetList:t(16,198)=(16,199)=s8charset_count:(0,1),0,32;\charset_list:(16,200)=*(9,35),32,32;; :T(16,201)=eXOMOrientation_LTR_TTB:0,XOMOrientation_RTL_TTB:1,\XOMOrientation_TTB_LTR:2,XOMOrientation_TTB_RTL:3,\XOMOrientation_Context:4,;XOrientation:t(16,202)=(16,201)XOMOrientation:t(16,203)=(16,204)=s8num_orientation:(0,1),0,32;\orientation:(16,205)=*(16,202),32,32;;XOMFontInfo:t(16,206)=(16,207)=s12num_font:(0,1),0,32;font_struct_list:(16,208)=*(16,183),32,32;\font_name_list:(16,200),64,32;;XIM:t(16,209)=(16,210)=*(16,211)=xs_XIM:XIC:t(16,212)=(16,213)=*(16,214)=xs_XIC:XIMProc:t(16,215)=(16,216)=*(16,217)=f(0,19)XICProc:t(16,218)=(16,219)=*(16,220)=f(0,1)XIDProc:t(16,221)=(16,222)=*(16,223)=f(0,19)XIMStyle:t(16,224)=(0,5)XIMStyles:t(16,225)=(16,226)=s8count_styles:(0,9),0,16;\supported_styles:(16,227)=*(16,224),32,32;;XVaNestedList:t(16,228)=(8,2)XIMCallback:t(16,229)=(16,230)=s8client_data:(16,1),0,32;\callback:(16,215),32,32;;XICCallback:t(16,231)=(16,232)=s8client_data:(16,1),0,32;\callback:(16,218),32,32;;XIMFeedback:t(16,233)=(0,5)_XIMText:T(16,234)=s16length:(0,9),0,16;feedback:(16,235)=*(16,233),32,32;\encoding_is_wchar:(0,1),64,32;string:(16,236)=u4multi_byte:(9,35),0,32;\wide_char:(16,197),0,32;;,96,32;;XIMText:t(16,237)=(16,234)XIMPreeditState:t(16,238)=(0,5)_XIMPreeditStateNotifyCallbackStruct:T(16,239)=s4state:(16,238),0,32;;XIMPreeditStateNotifyCallbackStruct:t(16,240)=(16,239)XIMResetState:t(16,241)=(0,5)XIMStringConversionFeedback:t(16,242)=(0,5)_XIMStringConversionText:T(16,243)=s16length:(0,9),0,16;\feedback:(16,244)=*(16,242),32,32;encoding_is_wchar:(0,1),64,32;\string:(16,245)=u4mbs:(9,35),0,32;wcs:(16,197),0,32;;,96,32;;XIMStringConversionText:t(16,246)=(16,243)XIMStringConversionPosition:t(16,247)=(0,9)XIMStringConversionType:t(16,248)=(0,9)XIMStringConversionOperation:t(16,249)=(0,9) :T(16,250)=eXIMForwardChar:0,XIMBackwardChar:1,XIMForwardWord:2,\XIMBackwardWord:3,XIMCaretUp:4,XIMCaretDown:5,\XIMNextLine:6,XIMPreviousLine:7,XIMLineStart:8,\XIMLineEnd:9,XIMAbsolutePosition:10,XIMDontChange:11,;XIMCaretDirection:t(16,251)=(16,250)_XIMStringConversionCallbackStruct:T(16,252)=s16position:(16,247),0,16;\direction:(16,251),32,32;operation:(16,249),64,16;\factor:(0,9),80,16;text:(16,253)=*(16,246),96,32;;XIMStringConversionCallbackStruct:t(16,254)=(16,252)_XIMPreeditDrawCallbackStruct:T(16,255)=s16caret:(0,1),0,32;\chg_first:(0,1),32,32;chg_length:(0,1),64,32;\text:(16,256)=*(16,237),96,32;;XIMPreeditDrawCallbackStruct:t(16,257)=(16,255) :T(16,258)=eXIMIsInvisible:0,XIMIsPrimary:1,XIMIsSecondary:2,;XIMCaretStyle:t(16,259)=(16,258)_XIMPreeditCaretCallbackStruct:T(16,260)=s12position:(0,1),0,32;\direction:(16,251),32,32;style:(16,259),64,32;;XIMPreeditCaretCallbackStruct:t(16,261)=(16,260) :T(16,262)=eXIMTextType:0,XIMBitmapType:1,;XIMStatusDataType:t(16,263)=(16,262)_XIMStatusDrawCallbackStruct:T(16,264)=s8type:(16,263),0,32;\data:(16,265)=u4text:(16,256),0,32;bitmap:(25,9),0,32;;,32,32;;XIMStatusDrawCallbackStruct:t(16,266)=(16,264)_XIMHotKeyTrigger:T(16,267)=s12keysym:(25,13),0,32;modifier:(0,1),32,32;\modifier_mask:(0,1),64,32;;XIMHotKeyTrigger:t(16,268)=(16,267)_XIMHotKeyTriggers:T(16,269)=s8num_hot_key:(0,1),0,32;\key:(16,270)=*(16,268),32,32;;XIMHotKeyTriggers:t(16,271)=(16,269)XIMHotKeyState:t(16,272)=(0,5)XIMValuesList:t(16,273)=(16,274)=s8count_values:(0,9),0,16;\supported_values:(16,200),32,32;;XErrorHandler:t(16,275)=(16,276)=*(16,277)=f(0,1)XIOErrorHandler:t(16,278)=(16,279)=*(16,280)=f(0,1)XConnectionWatchProc:t(16,281)=(16,282)=*(16,283)=f(0,19)Tk_BindingTable:t(15,1)=(15,2)=*(15,3)=xsTk_BindingTable_:Tk_Canvas:t(15,4)=(15,5)=*(15,6)=xsTk_Canvas_:Tk_Cursor:t(15,7)=(15,8)=*(15,9)=xsTk_Cursor_:Tk_ErrorHandler:t(15,10)=(15,11)=*(15,12)=xsTk_ErrorHandler_:Tk_Font:t(15,13)=(15,14)=*(15,15)=xsTk_Font_:Tk_Image:t(15,16)=(15,17)=*(15,18)=xsTk_Image__:Tk_ImageMaster:t(15,19)=(15,20)=*(15,21)=xsTk_ImageMaster_:Tk_TextLayout:t(15,22)=(15,23)=*(15,24)=xsTk_TextLayout_:Tk_Window:t(15,25)=(15,26)=*(15,27)=xsTk_Window_:Tk_3DBorder:t(15,28)=(15,29)=*(15,30)=xsTk_3DBorder_:Tk_Uid:t(15,31)=(9,35)Tk_ArgvInfo:t(15,32)=(15,33)=s20key:(9,35),0,32;type:(0,1),32,32;\src:(9,35),64,32;dst:(9,35),96,32;help:(9,35),128,32;;Tk_OptionParseProc:t(15,34)=(15,35)=f(0,1)Tk_OptionPrintProc:t(15,36)=(15,37)=f(9,35)Tk_CustomOption:T(15,38)=s12parseProc:(15,39)=*(15,34),0,32;\printProc:(15,40)=*(15,36),32,32;clientData:(1,1),64,32;;Tk_CustomOption:t(15,41)=(15,38)Tk_ConfigSpec:T(15,42)=s32type:(0,1),0,32;argvName:(9,35),32,32;\dbName:(9,35),64,32;dbClass:(9,35),96,32;defValue:(9,35),128,32;\offset:(0,1),160,32;specFlags:(0,1),192,32;customPtr:(15,43)=*(15,41),224,32;;Tk_ConfigSpec:t(15,44)=(15,42) :T(15,45)=eTK_DEFER_EVENT:0,TK_PROCESS_EVENT:1,\TK_DISCARD_EVENT:2,;Tk_RestrictAction:t(15,46)=(15,45) :T(15,47)=eTK_ANCHOR_N:0,TK_ANCHOR_NE:1,TK_ANCHOR_E:2,\TK_ANCHOR_SE:3,TK_ANCHOR_S:4,TK_ANCHOR_SW:5,\TK_ANCHOR_W:6,TK_ANCHOR_NW:7,TK_ANCHOR_CENTER:8,;Tk_Anchor:t(15,48)=(15,47) :T(15,49)=eTK_JUSTIFY_LEFT:0,TK_JUSTIFY_RIGHT:1,\TK_JUSTIFY_CENTER:2,;Tk_Justify:t(15,50)=(15,49)Tk_FontMetrics:T(15,51)=s12ascent:(0,1),0,32;descent:(0,1),32,32;\linespace:(0,1),64,32;;Tk_FontMetrics:t(15,52)=(15,51)Tk_GeomRequestProc:t(15,53)=(15,54)=f(0,19)Tk_GeomLostSlaveProc:t(15,55)=(15,54)Tk_GeomMgr:T(15,56)=s12name:(9,35),0,32;requestProc:(15,57)=*(15,53),32,32;\lostSlaveProc:(15,58)=*(15,55),64,32;;Tk_GeomMgr:t(15,59)=(15,56)XVirtualEvent:t(15,60)=(15,61)=s60type:(0,1),0,32;serial:(0,5),32,32;\event:(25,6),128,32;root:(25,6),160,32;subwindow:(25,6),192,32;\name:(15,31),416,32;same_screen:(0,1),448,32;;XActivateDeactivateEvent:t(15,62)=(15,63)=s20type:(0,1),0,32;\XActivateEvent:t(15,64)=(15,62)XDeactivateEvent:t(15,65)=(15,62)Tk_FakeWin:T(15,66)=s216display:(16,89),0,32;dummy1:(9,35),32,32;\screenNum:(0,1),64,32;visual:(16,21),96,32;depth:(0,1),128,32;\window:(25,6),160,32;dummy2:(9,35),192,32;dummy3:(9,35),224,32;\parentPtr:(15,25),256,32;dummy4:(9,35),288,32;dummy5:(9,35),320,32;\pathName:(9,35),352,32;nameUid:(15,31),384,32;classUid:(15,31),416,32;\changes:(16,52),448,224;dummy6:(0,4),672,32;atts:(16,29),704,480;\dummy7:(0,5),1184,32;flags:(0,4),1216,32;dummy8:(9,35),1248,32;\dummy9:(16,212),1280,32;dummy10:(15,67)=*(1,1),1312,32;\dummy11:(0,1),1344,32;dummy12:(0,1),1376,32;dummy13:(9,35),1408,32;\dummy14:(9,35),1440,32;dummy15:(1,1),1472,32;reqWidth:(0,1),1504,32;\reqHeight:(0,1),1536,32;internalBorderWidth:(0,1),1568,32;\dummy16:(9,35),1600,32;dummy17:(9,35),1632,32;dummy18:(1,1),1664,32;\dummy19:(9,35),1696,32;;Tk_FakeWin:t(15,68)=(15,66)Tk_Item:T(15,69)=s52id:(0,1),0,32;nextPtr:(15,70)=*(15,69),32,32;\staticTagSpace:(15,71)=ar(0,0);0;2;(15,31),64,96;tagPtr:(15,72)=*(15,31),160,32;\tagSpace:(0,1),192,32;numTags:(0,1),224,32;typePtr:(15,73)=*(15,74)=xsTk_ItemType:,256,32;\x1:(0,1),288,32;y1:(0,1),320,32;x2:(0,1),352,32;\y2:(0,1),384,32;;Tk_Item:t(15,75)=(15,69)Tk_ItemCreateProc:t(15,76)=(15,77)=f(0,1)Tk_ItemConfigureProc:t(15,78)=(15,79)=f(0,1)Tk_ItemCoordProc:t(15,80)=(15,77)Tk_ItemDeleteProc:t(15,81)=(15,82)=f(0,19)Tk_ItemDisplayProc:t(15,83)=(15,84)=f(0,19)Tk_ItemPointProc:t(15,85)=(15,86)=f(0,13)Tk_ItemAreaProc:t(15,87)=(15,88)=f(0,1)Tk_ItemPostscriptProc:t(15,89)=(15,90)=f(0,1)Tk_ItemScaleProc:t(15,91)=(15,92)=f(0,19)Tk_ItemTranslateProc:t(15,93)=(15,94)=f(0,19)Tk_ItemIndexProc:t(15,95)=(15,96)=f(0,1)Tk_ItemCursorProc:t(15,97)=(15,98)=f(0,19)Tk_ItemSelectionProc:t(15,99)=(15,100)=f(0,1)Tk_ItemInsertProc:t(15,101)=(15,102)=f(0,19)Tk_ItemDCharsProc:t(15,103)=(15,104)=f(0,19)Tk_ItemType:T(15,74)=s80name:(9,35),0,32;itemSize:(0,1),32,32;\createProc:(15,105)=*(15,76),64,32;configSpecs:(15,106)=*(15,44),96,32;\configProc:(15,107)=*(15,78),128,32;coordProc:(15,108)=*(15,80),160,32;\deleteProc:(15,109)=*(15,81),192,32;displayProc:(15,110)=*(15,83),224,32;\alwaysRedraw:(0,1),256,32;pointProc:(15,111)=*(15,85),288,32;\areaProc:(15,112)=*(15,87),320,32;postscriptProc:(15,113)=*(15,89),352,32;\scaleProc:(15,114)=*(15,91),384,32;translateProc:(15,115)=*(15,93),416,32;\indexProc:(15,116)=*(15,95),448,32;icursorProc:(15,117)=*(15,97),480,32;\selectionProc:(15,118)=*(15,99),512,32;insertProc:(15,119)=*(15,101),544,32;\dCharsProc:(15,120)=*(15,103),576,32;nextPtr:(15,73),608,32;;Tk_ItemType:t(15,121)=(15,74)Tk_CanvasTextInfo:T(15,122)=s56selBorder:(15,28),0,32;selBorderWidth:(0,1),32,32;\selFgColorPtr:(15,123)=*(16,54),64,32;selItemPtr:(15,124)=*(15,75),96,32;\selectFirst:(0,1),128,32;selectLast:(0,1),160,32;\anchorItemPtr:(15,124),192,32;selectAnchor:(0,1),224,32;\insertBorder:(15,28),256,32;insertWidth:(0,1),288,32;\insertBorderWidth:(0,1),320,32;focusItemPtr:(15,124),352,32;\gotFocus:(0,1),384,32;cursorOn:(0,1),416,32;;Tk_CanvasTextInfo:t(15,125)=(15,122)Tk_ImageType:t(15,126)=(15,127)=xsTk_ImageType:Tk_ImageCreateProc:t(15,128)=(15,129)=f(0,1)Tk_ImageGetProc:t(15,130)=(15,131)=f(1,1)Tk_ImageDisplayProc:t(15,132)=(15,133)=f(0,19)Tk_ImageFreeProc:t(15,134)=(15,135)=f(0,19)Tk_ImageDeleteProc:t(15,136)=(1,43)Tk_ImageChangedProc:t(15,137)=(15,138)=f(0,19)Tk_ImageType:T(15,127)=s28name:(9,35),0,32;createProc:(15,139)=*(15,128),32,32;\getProc:(15,140)=*(15,130),64,32;displayProc:(15,141)=*(15,132),96,32;\freeProc:(15,142)=*(15,134),128,32;deleteProc:(15,143)=*(15,136),160,32;\nextPtr:(15,144)=*(15,127),192,32;;Tk_PhotoHandle:t(15,145)=(8,2)Tk_PhotoImageBlock:T(15,146)=s32pixelPtr:(15,147)=*(0,11),0,32;\width:(0,1),32,32;height:(0,1),64,32;pitch:(0,1),96,32;\pixelSize:(0,1),128,32;offset:(15,148)=ar(0,0);0;2;(0,1),160,96;;Tk_PhotoImageBlock:t(15,149)=(15,146)Tk_PhotoImageFormat:t(15,150)=(15,151)=xsTk_PhotoImageFormat:Tk_ImageFileMatchProc:t(15,152)=(15,153)=f(0,1)Tk_ImageStringMatchProc:t(15,154)=(15,155)=f(0,1)Tk_ImageFileReadProc:t(15,156)=(15,157)=f(0,1)Tk_ImageStringReadProc:t(15,158)=(15,159)=f(0,1)Tk_ImageFileWriteProc:t(15,160)=(15,161)=f(0,1)Tk_ImageStringWriteProc:t(15,162)=(15,163)=f(0,1)Tk_PhotoImageFormat:T(15,151)=s32name:(9,35),0,32;fileMatchProc:(15,164)=*(15,152),32,32;\stringMatchProc:(15,165)=*(15,154),64,32;fileReadProc:(15,166)=*(15,156),96,32;\stringReadProc:(15,167)=*(15,158),128,32;fileWriteProc:(15,168)=*(15,160),160,32;\stringWriteProc:(15,169)=*(15,162),192,32;nextPtr:(15,170)=*(15,151),224,32;;Tk_ErrorProc:t(15,171)=(15,172)=f(0,1)Tk_EventProc:t(15,173)=(15,174)=f(0,19)Tk_GenericProc:t(15,175)=(15,176)=f(0,1)Tk_GetSelProc:t(15,177)=(15,178)=f(0,1)Tk_LostSelProc:t(15,179)=(1,43)Tk_RestrictProc:t(15,180)=(15,181)=f(15,46)Tk_SelectionProc:t(15,182)=(15,183)=f(0,1)../src/tick.xbmtick_bits:S(30,1)=ar(0,1);0;-1;(0,2)../src/cross.xbmcross_bits:S(31,1)=ar(0,1);0;-1;(0,2)../src/uparrow.xbmuparrow_bits:S(32,1)=ar(0,1);0;-1;(0,2)../src/downarrow.xbmdownarrow_bits:S(33,1)=ar(0,1);0;-1;(0,2)../src/phone.xbmphone_bits:S(34,1)=ar(0,1);0;-1;(0,2)../src/phone1.xbmphone1_bits:S(35,1)=ar(0,1);0;-1;(0,2)../src/phone2.xbmphone2_bits:S(36,1)=ar(0,1);0;-1;(0,2)../src/phone3.xbmphone3_bits:S(37,1)=ar(0,1);0;-1;(0,2)../src/phone4.xbmphone4_bits:S(38,1)=ar(0,1);0;-1;(0,2)../src/mail.xbmmail_bits:S(39,1)=ar(0,1);0;-1;(0,2)../src/eye.xbmeye_bits:S(40,1)=ar(0,1);0;-1;(0,11)../src/audio.xbmaudio_bits:S(41,1)=ar(0,1);0;-1;(0,11)../src/wb.xbmwb_bits:S(42,1)=ar(0,1);0;-1;(0,11)../src/text.xbmtext_bits:S(43,1)=ar(0,1);0;-1;(0,11)../src/unknown.xbmunknown_bits:S(44,1)=ar(0,1);0;-1;(0,2)../src/clock.xbmclock_bits:S(45,1)=ar(0,1);0;-1;(0,2)../src/www.xbmwww_bits:S(46,1)=ar(0,1);0;-1;(0,2)../src/ucl.xbmucl_bits:S(47,1)=ar(0,1);0;-1;(0,2)../src/tools.xbmtools_bits:S(48,1)=ar(0,1);0;-1;(0,2)../src/bullet0.xbmbullet0_bits:S(49,1)=ar(0,1);0;-1;(0,2)../src/bullet1.xbmbullet1_bits:S(50,1)=ar(0,1);0;-1;(0,2)../src/broadcast.xbmbroadcast_bits:S(51,1)=ar(0,1);0;-1;(0,2)../src/meeting.xbmmeeting_bits:S(52,1)=ar(0,1);0;-1;(0,2)../src/test.xbmtest_bits:S(53,1)=ar(0,1);0;-1;(0,2)../src/secure.xbmsecure_bits:S(54,1)=ar(0,1);0;-1;(0,2)../src/sbroadcast.xbmsbroadcast_bits:S(55,1)=ar(0,1);0;-1;(0,2)../src/smeeting.xbmsmeeting_bits:S(56,1)=ar(0,1);0;-1;(0,2)../src/stest.xbmstest_bits:S(57,1)=ar(0,1);0;-1;(0,2)../src/sdr.xbmsdr_bits:S(58,1)=ar(0,1);0;-1;(0,2)init_bitmaps:F(0,19)../src/bus.c../src/sdr.h/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/stdlib.hdiv_t:t(15,1)=(15,2)=s8quot:(0,1),0,32;rem:(0,1),32,32;;ldiv_t:t(15,3)=(15,4)=s8quot:(0,3),0,32;rem:(0,3),32,32;;random_data:T(15,5)=s28fptr:(15,6)=*(17,27),0,32;rptr:(15,6),32,32;\state:(15,6),64,32;rand_type:(0,1),96,32;rand_deg:(0,1),128,32;\rand_sep:(0,1),160,32;end_ptr:(15,6),192,32;;drand48_data:T(15,7)=s24x:(15,8)=ar(0,0);0;2;(0,9),0,48;\a:(15,8),48,48;c:(0,9),96,16;old_x:(15,8),112,48;\init:(0,1),160,32;;/usr/include/alloca.h__compar_fn_t:t(15,9)=(15,10)=*(15,11)=f(0,1)/usr/include/sys/socket.h/usr/include/bits/socket.hsocklen_t:t(29,1)=(0,4)__socket_type:T(29,2)=eSOCK_STREAM:1,SOCK_DGRAM:2,\SOCK_RAW:3,SOCK_RDM:4,SOCK_SEQPACKET:5,\SOCK_PACKET:10,;/usr/include/bits/sockaddr.hsa_family_t:t(31,1)=(0,9)sockaddr:T(29,3)=s16sa_family:(31,1),0,16;sa_data:(29,4)=ar(0,0);0;13;(0,2),16,112;; :T(29,5)=eMSG_OOB:1,MSG_PEEK:2,MSG_DONTROUTE:4,\MSG_CTRUNC:8,MSG_PROXY:16,;msghdr:T(29,6)=s28msg_name:(8,2),0,32;msg_namelen:(29,1),32,32;\msg_iov:(29,7)=*(29,8)=xsiovec:,64,32;msg_iovlen:(7,1),96,32;\msg_control:(8,2),128,32;msg_controllen:(7,1),160,32;\msg_flags:(0,1),192,32;;cmsghdr:T(29,9)=s12cmsg_len:(7,1),0,32;cmsg_level:(0,1),32,32;\cmsg_type:(0,1),64,32;__cmsg_data:(29,10)=ar(0,0);0;-1;(0,11),96,0;; :T(29,11)=eSCM_RIGHTS:1,__SCM_CREDENTIALS:2,__SCM_CONNECT:3,;/usr/include/asm/socket.hlinger:T(29,12)=s8l_onoff:(0,1),0,32;l_linger:(0,1),32,32;;/usr/include/bits/sockunion.h/usr/include/netash/ash.hsockaddr_ash:T(34,1)=s32sash_family:(31,1),0,16;sash_ifindex:(0,1),32,32;\sash_channel:(0,11),64,8;sash_plen:(0,4),96,32;\sash_prefix:(34,2)=ar(0,0);0;15;(0,11),128,128;;/usr/include/netatalk/at.h/usr/include/asm/types.humode_t:t(36,1)=(0,9)__s8:t(36,2)=(0,10)__u8:t(36,3)=(0,11)__s16:t(36,4)=(0,8)__u16:t(36,5)=(0,9)__s32:t(36,6)=(0,1)__u32:t(36,7)=(0,4)__s64:t(36,8)=(0,6)__u64:t(36,9)=(0,7)/usr/include/linux/atalk.hat_addr:T(38,1)=s4s_net:(36,5),0,16;s_node:(36,3),16,8;;sockaddr_at:T(38,2)=s16sat_family:(0,8),0,16;sat_port:(36,3),16,8;\sat_addr:(38,1),32,32;sat_zero:(38,3)=ar(0,0);0;7;(0,2),64,64;;netrange:T(38,4)=s8nr_phase:(36,3),0,8;nr_firstnet:(36,5),16,16;\nr_lastnet:(36,5),32,16;;atalk_route:T(38,5)=s20dev:(38,6)=*(38,7)=xsdevice:,0,32;\target:(38,1),32,32;gateway:(38,1),64,32;flags:(0,1),96,32;\next:(38,8)=*(38,5),128,32;;atalk_iface:T(38,9)=s24dev:(38,6),0,32;address:(38,1),32,32;\status:(0,1),64,32;nets:(38,4),96,64;next:(38,10)=*(38,9),160,32;;atalk_sock:T(38,11)=s8dest_net:(0,9),0,16;src_net:(0,9),16,16;\dest_node:(0,11),32,8;src_node:(0,11),40,8;\dest_port:(0,11),48,8;src_port:(0,11),56,8;;/usr/include/netax25/ax25.hax25_address:t(39,1)=(39,2)=s8ax25_call:(39,3)=ar(0,0);0;6;(0,2),0,56;;sockaddr_ax25:T(39,4)=s16sax25_family:(31,1),0,16;sax25_call:(39,1),32,64;\sax25_ndigis:(0,1),96,32;;full_sockaddr_ax25:T(39,5)=s80fsa_ax25:(39,4),0,128;fsa_digipeater:(39,6)=ar(0,0);0;7;(39,1),128,512;;ax25_routes_struct:T(39,7)=s84port_addr:(39,1),0,64;dest_addr:(39,1),64,64;\digi_count:(0,11),128,8;digi_addr:(39,6),160,512;;ax25_ctl_struct:T(39,8)=s32port_addr:(39,1),0,64;source_addr:(39,1),64,64;\dest_addr:(39,1),128,64;cmd:(0,4),192,32;arg:(0,5),224,32;;ax25_route_opt_struct:T(39,9)=s24port_addr:(39,1),0,64;\dest_addr:(39,1),64,64;cmd:(0,1),128,32;arg:(0,1),160,32;;ax25_bpqaddr_struct:T(39,10)=s24dev:(39,11)=ar(0,0);0;15;(0,2),0,128;\addr:(39,1),128,64;;ax25_parms_struct:T(39,12)=s48port_addr:(39,1),0,64;values:(39,13)=ar(0,0);0;19;(0,9),64,320;;/usr/include/netinet/in.h/usr/include/stdint.huint8_t:t(41,1)=(0,11)uint16_t:t(41,2)=(0,9)uint32_t:t(41,3)=(0,4)uint64_t:t(41,4)=(0,7)int_least8_t:t(41,5)=(0,10)int_least16_t:t(41,6)=(0,8)int_least32_t:t(41,7)=(0,1)int_least64_t:t(41,8)=(0,6)uint_least8_t:t(41,9)=(0,11)uint_least16_t:t(41,10)=(0,9)uint_least32_t:t(41,11)=(0,4)uint_least64_t:t(41,12)=(0,7)int_fast8_t:t(41,13)=(0,10)int_fast16_t:t(41,14)=(0,1)int_fast32_t:t(41,15)=(0,1)int_fast64_t:t(41,16)=(0,6)uint_fast8_t:t(41,17)=(0,11)uint_fast16_t:t(41,18)=(0,4)uint_fast32_t:t(41,19)=(0,4)uint_fast64_t:t(41,20)=(0,7)intptr_t:t(41,21)=(0,1)uintptr_t:t(41,22)=(0,4)intmax_t:t(41,23)=(0,6)uintmax_t:t(41,24)=(0,7) :T(40,1)=eIPPROTO_IP:0,IPPROTO_HOPOPTS:0,IPPROTO_ICMP:1,\IPPROTO_IGMP:2,IPPROTO_IPIP:4,IPPROTO_TCP:6,\IPPROTO_EGP:8,IPPROTO_PUP:12,IPPROTO_UDP:17,\IPPROTO_IDP:22,IPPROTO_IPV6:41,IPPROTO_ROUTING:43,\IPPROTO_FRAGMENT:44,IPPROTO_ESP:50,IPPROTO_AH:51,\IPPROTO_ICMPV6:58,IPPROTO_NONE:59,IPPROTO_DSTOPTS:60,\IPPROTO_RAW:255,IPPROTO_MAX:256,; :T(40,2)=eIPPORT_ECHO:7,IPPORT_DISCARD:9,IPPORT_SYSTAT:11,\IPPORT_DAYTIME:13,IPPORT_NETSTAT:15,IPPORT_FTP:21,\IPPORT_TELNET:23,IPPORT_SMTP:25,IPPORT_TIMESERVER:37,\IPPORT_NAMESERVER:42,IPPORT_WHOIS:43,IPPORT_MTP:57,\IPPORT_TFTP:69,IPPORT_RJE:77,IPPORT_FINGER:79,\IPPORT_TTYLINK:87,IPPORT_SUPDUP:95,IPPORT_EXECSERVER:512,\IPPORT_LOGINSERVER:513,IPPORT_CMDSERVER:514,IPPORT_EFSSERVER:520,\IPPORT_BIFFUDP:512,IPPORT_WHOSERVER:513,IPPORT_ROUTESERVER:520,\IPPORT_RESERVED:1024,IPPORT_USERRESERVED:5000,;in_addr:T(40,3)=s4s_addr:(41,3),0,32;;in6_addr:T(40,4)=s16in6_u:(40,5)=u16u6_addr8:(40,6)=ar(0,0);0;15;(41,1),0,128;\u6_addr16:(40,7)=ar(0,0);0;7;(41,2),0,128;u6_addr32:(40,8)=ar(0,0);0;3;(41,3),0,128;\u6_addr64:(40,9)=ar(0,0);0;1;(41,4),0,128;;,0,128;;sockaddr_in:T(40,10)=s16sin_family:(31,1),0,16;sin_port:(41,2),16,16;\sin_addr:(40,3),32,32;sin_zero:(40,11)=ar(0,0);0;7;(0,11),64,64;;sockaddr_in6:T(40,12)=s24sin6_family:(31,1),0,16;sin6_port:(41,2),16,16;\sin6_flowinfo:(41,3),32,32;sin6_addr:(40,4),64,128;;ipv6_mreq:T(40,13)=s20ipv6mr_multiaddr:(40,4),0,128;ipv6mr_ifindex:(0,4),128,32;;/usr/include/bits/in.hip_opts:T(43,1)=s44ip_dst:(40,3),0,32;ip_opts:(43,2)=ar(0,0);0;39;(0,2),32,320;;ip_mreq:T(43,3)=s8imr_multiaddr:(40,3),0,32;imr_interface:(40,3),32,32;;/usr/include/bits/byteswap.hin6_pktinfo:T(40,14)=s20ipi6_addr:(40,4),0,128;ipi6_ifindex:(0,4),128,32;;/usr/include/netipx/ipx.hsockaddr_ipx:T(45,1)=s16sipx_family:(31,1),0,16;sipx_port:(17,30),16,16;\sipx_network:(17,31),32,32;sipx_node:(45,2)=ar(0,0);0;5;(0,11),64,48;\sipx_type:(17,29),112,8;sipx_zero:(0,11),120,8;;ipx_route_definition:T(45,3)=s16ipx_network:(0,5),0,32;\ipx_router_network:(0,5),32,32;ipx_router_node:(45,2),64,48;;ipx_route_definition:t(45,4)=(45,3)ipx_interface_definition:T(45,5)=s28ipx_network:(0,5),0,32;\ipx_device:(34,2),32,128;ipx_dlink_type:(0,11),160,8;\ipx_special:(0,11),168,8;ipx_node:(45,2),176,48;;ipx_interface_definition:t(45,6)=(45,5)ipx_config_data:T(45,7)=s4ipxcfg_auto_select_primary:(0,11),0,8;\ipxcfg_auto_create_interfaces:(0,11),8,8;;ipx_config_data:t(45,8)=(45,7)ipx_route_def:T(45,9)=s32ipx_network:(0,5),0,32;ipx_router_network:(0,5),32,32;\ipx_router_node:(45,2),64,48;ipx_device:(34,2),112,128;\ipx_flags:(0,9),240,16;;/usr/include/netrose/rose.hrose_address:t(47,1)=(47,2)=s8rose_addr:(47,3)=ar(0,0);0;4;(0,2),0,40;;sockaddr_rose:T(47,4)=s32srose_family:(31,1),0,16;srose_addr:(47,1),32,64;\srose_call:(39,1),96,64;srose_ndigis:(0,1),160,32;\srose_digi:(39,1),192,64;;rose_route_struct:T(47,5)=s104address:(47,1),0,64;mask:(0,9),64,16;\neighbour:(39,1),96,64;device:(39,11),160,128;ndigis:(0,11),288,8;\digipeaters:(39,6),320,512;;rose_cause_struct:T(47,6)=s4cause:(0,11),0,8;diagnostic:(0,11),8,8;;/usr/include/sys/un.h/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/string.h/usr/include/bits/string.h/usr/include/bits/string2.hsockaddr_un:T(48,1)=s112sun_family:(31,1),0,16;sun_path:(48,2)=ar(0,0);0;107;(0,2),16,864;;sockaddr_union:T(33,1)=u128sa:(29,3),0,128;sash:(34,1),0,256;\sat:(38,2),0,128;sax25:(39,4),0,128;sin:(40,10),0,128;\sin6:(40,12),0,192;sipx:(45,1),0,128;rose:(47,4),0,256;\sun:(48,1),0,896;__maxsize:(33,2)=ar(0,0);0;127;(0,2),0,1024;;osockaddr:T(27,1)=s16sa_family:(0,9),0,16;sa_data:(27,2)=ar(0,0);0;13;(0,11),16,112;;__SOCKADDR_ARG:t(27,3)=(27,4)=u4__sockaddr__:(27,5)=*(29,3),0,32;\__sockaddr_at__:(27,6)=*(38,2),0,32;__sockaddr_ax25__:(27,7)=*(39,4),0,32;\__sockaddr_dl__:(27,8)=*(27,9)=xssockaddr_dl:,0,32;__sockaddr_eon__:(27,10)=*(27,11)=xssockaddr_eon:,0,32;\__sockaddr_in__:(27,12)=*(40,10),0,32;__sockaddr_in6__:(27,13)=*(40,12),0,32;\__sockaddr_inarp__:(27,14)=*(27,15)=xssockaddr_inarp:,0,32;__sockaddr_ipx__:(27,16)=*(45,1),0,32;\__sockaddr_iso__:(27,17)=*(27,18)=xssockaddr_iso:,0,32;__sockaddr_ns__:(27,19)=*(27,20)=xssockaddr_ns:,0,32;\__sockaddr_un__:(27,21)=*(48,1),0,32;__sockaddr_x25__:(27,22)=*(27,23)=xssockaddr_x25:,0,32;;__CONST_SOCKADDR_ARG:t(27,24)=(27,25)=u4__sockaddr__:(27,26)=*(29,3),0,32;\__sockaddr_at__:(27,27)=*(38,2),0,32;__sockaddr_ax25__:(27,28)=*(39,4),0,32;\__sockaddr_dl__:(27,29)=*(27,9),0,32;__sockaddr_eon__:(27,30)=*(27,11),0,32;\__sockaddr_in__:(27,31)=*(40,10),0,32;__sockaddr_in6__:(27,32)=*(40,12),0,32;\__sockaddr_inarp__:(27,33)=*(27,15),0,32;__sockaddr_ipx__:(27,34)=*(45,1),0,32;\__sockaddr_iso__:(27,35)=*(27,18),0,32;__sockaddr_ns__:(27,36)=*(27,20),0,32;\__sockaddr_un__:(27,37)=*(48,1),0,32;__sockaddr_x25__:(27,38)=*(27,23),0,32;;/usr/include/arpa/inet.h/usr/include/net/if.h :T(54,1)=eIFF_UP:1,IFF_BROADCAST:2,IFF_DEBUG:4,\IFF_LOOPBACK:8,IFF_POINTOPOINT:16,IFF_NOTRAILERS:32,\IFF_RUNNING:64,IFF_NOARP:128,IFF_PROMISC:256,\IFF_ALLMULTI:512,IFF_MASTER:1024,IFF_SLAVE:2048,\IFF_MULTICAST:4096,IFF_PORTSEL:8192,IFF_AUTOMEDIA:16384,;ifaddr:T(54,2)=s40ifa_addr:(29,3),0,128;ifa_ifu:(54,3)=u16ifu_broadaddr:(29,3),0,128;\ifu_dstaddr:(29,3),0,128;;,128,128;ifa_ifp:(54,4)=*(54,5)=xsiface:,256,32;\ifa_next:(54,6)=*(54,2),288,32;;ifmap:T(54,7)=s16mem_start:(0,5),0,32;mem_end:(0,5),32,32;\base_addr:(0,9),64,16;irq:(0,11),80,8;dma:(0,11),88,8;\port:(0,11),96,8;;ifreq:T(54,8)=s32ifr_ifrn:(54,9)=u16ifrn_name:(39,11),0,128;;,0,128;\ifr_ifru:(54,10)=u16ifru_addr:(29,3),0,128;ifru_dstaddr:(29,3),0,128;\ifru_broadaddr:(29,3),0,128;ifru_netmask:(29,3),0,128;\ifru_hwaddr:(29,3),0,128;ifru_flags:(0,8),0,16;\ifru_ivalue:(0,1),0,32;ifru_mtu:(0,1),0,32;\ifru_map:(54,7),0,128;ifru_slave:(39,11),0,128;\ifru_data:(9,34),0,32;;,128,128;;ifconf:T(54,11)=s8ifc_len:(0,1),0,32;ifc_ifcu:(54,12)=u4ifcu_buf:(9,34),0,32;\ifcu_req:(54,13)=*(54,8),0,32;;,32,32;;if_nameindex:T(54,14)=s8if_index:(0,4),0,32;if_name:(9,35),32,32;;/usr/include/sys/ioctl.h/usr/include/bits/ioctls.h/usr/include/asm/ioctls.h/usr/include/asm/ioctl.h/usr/include/bits/ioctl-types.hwinsize:T(59,1)=s8ws_row:(0,9),0,16;ws_col:(0,9),16,16;\ws_xpixel:(0,9),32,16;ws_ypixel:(0,9),48,16;;termio:T(59,2)=s20c_iflag:(0,9),0,16;c_oflag:(0,9),16,16;\c_cflag:(0,9),32,16;c_lflag:(0,9),48,16;c_line:(0,11),64,8;\c_cc:(40,11),72,64;;/usr/include/sys/ttydefaults.h/usr/include/netdb.h/usr/include/rpc/netdb.hrpcent:T(62,1)=s12r_name:(9,35),0,32;r_aliases:(62,2)=*(9,35),32,32;\r_number:(0,1),64,32;;hostent:T(61,1)=s20h_name:(9,35),0,32;h_aliases:(62,2),32,32;\h_addrtype:(0,1),64,32;h_length:(0,1),96,32;\h_addr_list:(62,2),128,32;;netent:T(61,2)=s16n_name:(9,35),0,32;n_aliases:(62,2),32,32;\n_addrtype:(0,1),64,32;n_net:(0,5),96,32;;servent:T(61,3)=s16s_name:(9,35),0,32;s_aliases:(62,2),32,32;\s_port:(0,1),64,32;s_proto:(9,35),96,32;;protoent:T(61,4)=s12p_name:(9,35),0,32;p_aliases:(62,2),32,32;\p_proto:(0,1),64,32;;addrinfo:T(61,5)=s32ai_flags:(0,1),0,32;ai_family:(0,1),32,32;\ai_socktype:(0,1),64,32;ai_protocol:(0,1),96,32;\ai_addrlen:(0,1),128,32;ai_addr:(27,5),160,32;\ai_canonname:(9,35),192,32;ai_next:(61,6)=*(61,5),224,32;;/usr/include/pwd.hpasswd:T(65,1)=s28pw_name:(9,35),0,32;pw_passwd:(9,35),32,32;\pw_uid:(9,18),64,32;pw_gid:(9,19),96,32;pw_gecos:(9,35),128,32;\pw_dir:(9,35),160,32;pw_shell:(9,35),192,32;;/usr/include/sys/time.h/usr/include/bits/time.htimeval:T(70,1)=s8tv_sec:(9,36),0,32;tv_usec:(9,36),32,32;;clock_t:t(68,1)=(9,38)tm:T(68,2)=s44tm_sec:(0,1),0,32;tm_min:(0,1),32,32;\tm_hour:(0,1),64,32;tm_mday:(0,1),96,32;tm_mon:(0,1),128,32;\tm_year:(0,1),160,32;tm_wday:(0,1),192,32;tm_yday:(0,1),224,32;\tm_isdst:(0,1),256,32;tm_gmtoff:(0,3),288,32;\tm_zone:(68,3)=*(0,2),320,32;;timezone:T(67,1)=s8tz_minuteswest:(0,1),0,32;tz_dsttime:(0,1),32,32;;__itimer_which:T(67,2)=eITIMER_REAL:0,ITIMER_VIRTUAL:1,\ITIMER_PROF:2,;itimerval:T(67,3)=s16it_interval:(70,1),0,64;it_value:(70,1),64,64;;/usr/include/sys/stat.h/usr/include/bits/stat.hstat:T(73,1)=s88st_dev:(9,17),0,64;__pad1:(0,9),64,16;\st_ino:(9,20),96,32;st_mode:(9,21),128,32;st_nlink:(9,22),160,32;\st_uid:(9,18),192,32;st_gid:(9,19),224,32;st_rdev:(9,17),256,64;\__pad2:(0,9),320,16;st_size:(9,23),352,32;st_blksize:(0,5),384,32;\st_blocks:(9,45),416,32;st_atime:(9,36),448,32;\__unused1:(0,5),480,32;st_mtime:(9,36),512,32;\__unused2:(0,5),544,32;st_ctime:(9,36),576,32;\__unused3:(0,5),608,32;__unused4:(0,5),640,32;\__unused5:(0,5),672,32;;/usr/include/ctype.h :T(74,1)=e_ISupper:256,_ISlower:512,_ISalpha:1024,\_ISdigit:2048,_ISxdigit:4096,_ISspace:8192,\_ISprint:16384,_ISgraph:32768,_ISblank:1,\_IScntrl:2,_ISpunct:4,_ISalnum:8,;/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/arpa/nameser.h/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/sys/param.h/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/limits.h/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/syslimits.h/usr/include/limits.h/usr/include/bits/posix1_lim.h/usr/include/bits/local_lim.h/usr/include/linux/limits.h/usr/include/asm/limits.h/usr/include/asm/page.h/usr/include/asm/proc/page.h/usr/include/bits/posix2_lim.h/usr/include/linux/param.h/usr/include/asm/param.h/usr/include/asm/proc/param.h/usr/include/sys/bitypes.hHEADER:t(75,1)=(75,2)=s12id:(0,4),0,16;rd:(0,4),16,1;\tc:(0,4),17,1;aa:(0,4),18,1;opcode:(0,4),19,4;\qr:(0,4),23,1;rcode:(0,4),24,4;cd:(0,4),28,1;\ad:(0,4),29,1;unused:(0,4),30,1;ra:(0,4),31,1;\qdcount:(0,4),32,16;ancount:(0,4),48,16;nscount:(0,4),64,16;\arcount:(0,4),80,16;;/usr/include/resolv.h__res_state:T(92,1)=s512retrans:(0,1),0,32;retry:(0,1),32,32;\options:(17,4),64,32;nscount:(0,1),96,32;nsaddr_list:(92,2)=ar(0,0);0;2;(40,10),128,384;\id:(17,2),512,16;dnsrch:(92,3)=ar(0,0);0;6;(9,35),544,224;\defdname:(92,4)=ar(0,0);0;255;(0,2),768,2048;pfcode:(17,4),2816,32;\ndots:(0,4),2848,4;nsort:(0,4),2852,4;unused:(92,5)=ar(0,0);0;2;(0,2),2856,24;\sort_list:(92,6)=ar(0,0);0;9;(92,7)=s8addr:(40,3),0,32;\mask:(17,31),32,32;;,2880,640;pad:(92,8)=ar(0,0);0;71;(0,2),3520,576;; :T(92,9)=eres_goahead:0,res_nextns:1,res_modified:2,\res_done:3,res_error:4,;res_sendhookact:t(92,10)=(92,9)res_send_qhook:t(92,11)=(92,12)=*(92,13)=f(92,10)res_send_rhook:t(92,14)=(92,15)=*(92,16)=f(92,10)res_sym:T(92,17)=s12number:(0,1),0,32;name:(9,35),32,32;\humanname:(9,35),64,32;;XPointer:t(96,1)=(9,35)_XExtData:T(96,2)=s16number:(0,1),0,32;next:(96,3)=*(96,2),32,32;\free_private:(96,4)=*(96,5)=f(0,1),64,32;private_data:(96,1),96,32;;XExtData:t(96,6)=(96,2)XExtCodes:t(96,7)=(96,8)=s16extension:(0,1),0,32;major_opcode:(0,1),32,32;\XPixmapFormatValues:t(96,9)=(96,10)=s12depth:(0,1),0,32;\XGCValues:t(96,11)=(96,12)=s92function:(0,1),0,32;plane_mask:(0,5),32,32;\arc_mode:(0,1),320,32;tile:(97,9),352,32;stipple:(97,9),384,32;\font:(97,8),480,32;subwindow_mode:(0,1),512,32;\clip_y_origin:(0,1),608,32;clip_mask:(97,9),640,32;\GC:t(96,13)=(96,14)=*(96,15)=xs_XGC:Visual:t(96,16)=(96,17)=s32ext_data:(96,18)=*(96,6),0,32;\visualid:(97,4),32,32;class:(0,1),64,32;red_mask:(0,5),96,32;\Depth:t(96,19)=(96,20)=s12depth:(0,1),0,32;nvisuals:(0,1),32,32;\visuals:(96,21)=*(96,16),64,32;;Screen:t(96,22)=(96,23)=s80ext_data:(96,18),0,32;display:(96,24)=*(96,25)=xs_XDisplay:,32,32;\root:(97,6),64,32;width:(0,1),96,32;height:(0,1),128,32;\depths:(96,26)=*(96,19),256,32;root_depth:(0,1),288,32;\root_visual:(96,21),320,32;default_gc:(96,13),352,32;\cmap:(97,11),384,32;white_pixel:(0,5),416,32;black_pixel:(0,5),448,32;\ScreenFormat:t(96,27)=(96,28)=s16ext_data:(96,18),0,32;\XSetWindowAttributes:t(96,29)=(96,30)=s60background_pixmap:(97,9),0,32;\background_pixel:(0,5),32,32;border_pixmap:(97,9),64,32;\colormap:(97,11),416,32;cursor:(97,10),448,32;;XWindowAttributes:t(96,31)=(96,32)=s92x:(0,1),0,32;y:(0,1),32,32;\depth:(0,1),160,32;visual:(96,21),192,32;root:(97,6),224,32;\colormap:(97,11),480,32;map_installed:(0,1),512,32;\override_redirect:(0,1),672,32;screen:(96,33)=*(96,22),704,32;;XHostAddress:t(96,34)=(96,35)=s12family:(0,1),0,32;length:(0,1),32,32;\funcs:T(96,36)=s24create_image:(96,37)=*(96,38)=f(96,39)=*(96,40)=xs_XImage:,0,32;\destroy_image:(96,41)=*(96,42)=f(0,1),32,32;get_pixel:(96,43)=*(96,44)=f(0,5),64,32;\put_pixel:(96,45)=*(96,46)=f(0,1),96,32;sub_image:(96,47)=*(96,48)=f(96,39),128,32;\add_pixel:(96,49)=*(96,50)=f(0,1),160,32;;_XImage:T(96,40)=s88width:(0,1),0,32;height:(0,1),32,32;\obdata:(96,1),480,32;f:(96,36),512,192;;XImage:t(96,51)=(96,40)XWindowChanges:t(96,52)=(96,53)=s28x:(0,1),0,32;y:(0,1),32,32;\sibling:(97,6),160,32;stack_mode:(0,1),192,32;;XColor:t(96,54)=(96,55)=s12pixel:(0,5),0,32;red:(0,9),32,16;\XSegment:t(96,56)=(96,57)=s8x1:(0,8),0,16;y1:(0,8),16,16;\XPoint:t(96,58)=(96,59)=s4x:(0,8),0,16;y:(0,8),16,16;;XRectangle:t(96,60)=(96,61)=s8x:(0,8),0,16;y:(0,8),16,16;\XArc:t(96,62)=(96,63)=s12x:(0,8),0,16;y:(0,8),16,16;\XKeyboardControl:t(96,64)=(96,65)=s32key_click_percent:(0,1),0,32;\XKeyboardState:t(96,66)=(96,67)=s56key_click_percent:(0,1),0,32;\global_auto_repeat:(0,1),160,32;auto_repeats:(96,68)=ar(0,0);0;31;(0,2),192,256;;XTimeCoord:t(96,69)=(96,70)=s8time:(97,5),0,32;x:(0,8),32,16;\XModifierKeymap:t(96,71)=(96,72)=s8max_keypermod:(0,1),0,32;\modifiermap:(96,73)=*(97,14),32,32;;Display:t(96,74)=(96,25)_XPrivDisplay:t(96,75)=(96,76)=*(96,77)=s176ext_data:(96,18),0,32;\private1:(96,78)=*(96,79)=xs_XPrivate:,32,32;fd:(0,1),64,32;\private3:(97,1),224,32;private4:(97,1),256,32;private5:(97,1),288,32;\private6:(0,1),320,32;resource_alloc:(96,80)=*(96,81)=f(97,1),352,32;\nformats:(0,1),512,32;pixmap_format:(96,82)=*(96,27),544,32;\private8:(0,1),576,32;release:(0,1),608,32;private9:(96,78),640,32;\private10:(96,78),672,32;qlen:(0,1),704,32;last_request_read:(0,5),736,32;\request:(0,5),768,32;private11:(96,1),800,32;private12:(96,1),832,32;\private13:(96,1),864,32;private14:(96,1),896,32;\max_request_size:(0,4),928,32;db:(96,83)=*(96,84)=xs_XrmHashBucketRec:,960,32;\private15:(96,85)=*(96,86)=f(0,1),992,32;display_name:(9,35),1024,32;\screens:(96,33),1120,32;motion_buffer:(0,5),1152,32;\max_keycode:(0,1),1248,32;private17:(96,1),1280,32;\private18:(96,1),1312,32;private19:(0,1),1344,32;\XKeyEvent:t(96,87)=(96,88)=s60type:(0,1),0,32;serial:(0,5),32,32;\send_event:(0,1),64,32;display:(96,89)=*(96,74),96,32;\window:(97,6),128,32;root:(97,6),160,32;subwindow:(97,6),192,32;\time:(97,5),224,32;x:(0,1),256,32;y:(0,1),288,32;\XKeyPressedEvent:t(96,90)=(96,87)XKeyReleasedEvent:t(96,91)=(96,87)XButtonEvent:t(96,92)=(96,93)=s60type:(0,1),0,32;serial:(0,5),32,32;\send_event:(0,1),64,32;display:(96,89),96,32;\XButtonPressedEvent:t(96,94)=(96,92)XButtonReleasedEvent:t(96,95)=(96,92)XMotionEvent:t(96,96)=(96,97)=s60type:(0,1),0,32;serial:(0,5),32,32;\XPointerMovedEvent:t(96,98)=(96,96)XCrossingEvent:t(96,99)=(96,100)=s68type:(0,1),0,32;serial:(0,5),32,32;\XEnterWindowEvent:t(96,101)=(96,99)XLeaveWindowEvent:t(96,102)=(96,99)XFocusChangeEvent:t(96,103)=(96,104)=s28type:(0,1),0,32;\serial:(0,5),32,32;send_event:(0,1),64,32;display:(96,89),96,32;\window:(97,6),128,32;mode:(0,1),160,32;detail:(0,1),192,32;;XFocusInEvent:t(96,105)=(96,103)XFocusOutEvent:t(96,106)=(96,103)XKeymapEvent:t(96,107)=(96,108)=s52type:(0,1),0,32;serial:(0,5),32,32;\window:(97,6),128,32;key_vector:(96,68),160,256;;XExposeEvent:t(96,109)=(96,110)=s40type:(0,1),0,32;serial:(0,5),32,32;\window:(97,6),128,32;x:(0,1),160,32;y:(0,1),192,32;\XGraphicsExposeEvent:t(96,111)=(96,112)=s48type:(0,1),0,32;\drawable:(97,7),128,32;x:(0,1),160,32;y:(0,1),192,32;\XNoExposeEvent:t(96,113)=(96,114)=s28type:(0,1),0,32;serial:(0,5),32,32;\drawable:(97,7),128,32;major_code:(0,1),160,32;\XVisibilityEvent:t(96,115)=(96,116)=s24type:(0,1),0,32;\window:(97,6),128,32;state:(0,1),160,32;;XCreateWindowEvent:t(96,117)=(96,118)=s48type:(0,1),0,32;\parent:(97,6),128,32;window:(97,6),160,32;x:(0,1),192,32;\XDestroyWindowEvent:t(96,119)=(96,120)=s24type:(0,1),0,32;\event:(97,6),128,32;window:(97,6),160,32;;XUnmapEvent:t(96,121)=(96,122)=s28type:(0,1),0,32;serial:(0,5),32,32;\event:(97,6),128,32;window:(97,6),160,32;from_configure:(0,1),192,32;;XMapEvent:t(96,123)=(96,124)=s28type:(0,1),0,32;serial:(0,5),32,32;\event:(97,6),128,32;window:(97,6),160,32;override_redirect:(0,1),192,32;;XMapRequestEvent:t(96,125)=(96,126)=s24type:(0,1),0,32;\parent:(97,6),128,32;window:(97,6),160,32;;XReparentEvent:t(96,127)=(96,128)=s40type:(0,1),0,32;serial:(0,5),32,32;\event:(97,6),128,32;window:(97,6),160,32;parent:(97,6),192,32;\XConfigureEvent:t(96,129)=(96,130)=s52type:(0,1),0,32;serial:(0,5),32,32;\event:(97,6),128,32;window:(97,6),160,32;x:(0,1),192,32;\border_width:(0,1),320,32;above:(97,6),352,32;\XGravityEvent:t(96,131)=(96,132)=s32type:(0,1),0,32;serial:(0,5),32,32;\XResizeRequestEvent:t(96,133)=(96,134)=s28type:(0,1),0,32;\window:(97,6),128,32;width:(0,1),160,32;height:(0,1),192,32;;XConfigureRequestEvent:t(96,135)=(96,136)=s56type:(0,1),0,32;\XCirculateEvent:t(96,137)=(96,138)=s28type:(0,1),0,32;serial:(0,5),32,32;\event:(97,6),128,32;window:(97,6),160,32;place:(0,1),192,32;;XCirculateRequestEvent:t(96,139)=(96,140)=s28type:(0,1),0,32;\parent:(97,6),128,32;window:(97,6),160,32;place:(0,1),192,32;;XPropertyEvent:t(96,141)=(96,142)=s32type:(0,1),0,32;serial:(0,5),32,32;\window:(97,6),128,32;atom:(97,3),160,32;time:(97,5),192,32;\XSelectionClearEvent:t(96,143)=(96,144)=s28type:(0,1),0,32;\window:(97,6),128,32;selection:(97,3),160,32;time:(97,5),192,32;;XSelectionRequestEvent:t(96,145)=(96,146)=s40type:(0,1),0,32;\owner:(97,6),128,32;requestor:(97,6),160,32;selection:(97,3),192,32;\target:(97,3),224,32;property:(97,3),256,32;time:(97,5),288,32;;XSelectionEvent:t(96,147)=(96,148)=s36type:(0,1),0,32;serial:(0,5),32,32;\requestor:(97,6),128,32;selection:(97,3),160,32;\target:(97,3),192,32;property:(97,3),224,32;time:(97,5),256,32;;XColormapEvent:t(96,149)=(96,150)=s32type:(0,1),0,32;serial:(0,5),32,32;\window:(97,6),128,32;colormap:(97,11),160,32;new:(0,1),192,32;\XClientMessageEvent:t(96,151)=(96,152)=s48type:(0,1),0,32;\window:(97,6),128,32;message_type:(97,3),160,32;\format:(0,1),192,32;data:(96,153)=u20b:(96,154)=ar(0,0);0;19;(0,2),0,160;\s:(96,155)=ar(0,0);0;9;(0,8),0,160;l:(96,156)=ar(0,0);0;4;(0,3),0,160;;,224,160;;XMappingEvent:t(96,157)=(96,158)=s32type:(0,1),0,32;serial:(0,5),32,32;\window:(97,6),128,32;request:(0,1),160,32;first_keycode:(0,1),192,32;\XErrorEvent:t(96,159)=(96,160)=s20type:(0,1),0,32;display:(96,89),32,32;\resourceid:(97,1),64,32;serial:(0,5),96,32;error_code:(0,11),128,8;\XAnyEvent:t(96,161)=(96,162)=s20type:(0,1),0,32;serial:(0,5),32,32;\window:(97,6),128,32;;_XEvent:T(96,163)=u96type:(0,1),0,32;xany:(96,161),0,160;\xkey:(96,87),0,480;xbutton:(96,92),0,480;xmotion:(96,96),0,480;\xcrossing:(96,99),0,544;xfocus:(96,103),0,224;xexpose:(96,109),0,320;\xgraphicsexpose:(96,111),0,384;xnoexpose:(96,113),0,224;\xvisibility:(96,115),0,192;xcreatewindow:(96,117),0,384;\xdestroywindow:(96,119),0,192;xunmap:(96,121),0,224;\xmap:(96,123),0,224;xmaprequest:(96,125),0,192;xreparent:(96,127),0,320;\xconfigure:(96,129),0,416;xgravity:(96,131),0,256;\xresizerequest:(96,133),0,224;xconfigurerequest:(96,135),0,448;\xcirculate:(96,137),0,224;xcirculaterequest:(96,139),0,224;\xproperty:(96,141),0,256;xselectionclear:(96,143),0,224;\xselectionrequest:(96,145),0,320;xselection:(96,147),0,288;\xcolormap:(96,149),0,256;xclient:(96,151),0,384;xmapping:(96,157),0,256;\xerror:(96,159),0,160;xkeymap:(96,107),0,416;pad:(96,164)=ar(0,0);0;23;(0,3),0,768;;XEvent:t(96,165)=(96,163)XCharStruct:t(96,166)=(96,167)=s12lbearing:(0,8),0,16;rbearing:(0,8),16,16;\XFontProp:t(96,168)=(96,169)=s8name:(97,3),0,32;card32:(0,5),32,32;;XFontStruct:t(96,170)=(96,171)=s80ext_data:(96,18),0,32;fid:(97,8),32,32;\properties:(96,172)=*(96,168),320,32;min_bounds:(96,166),352,96;\max_bounds:(96,166),448,96;per_char:(96,173)=*(96,166),544,32;\XTextItem:t(96,174)=(96,175)=s16chars:(9,35),0,32;nchars:(0,1),32,32;\delta:(0,1),64,32;font:(97,8),96,32;;XChar2b:t(96,176)=(96,177)=s4byte1:(0,11),0,8;byte2:(0,11),8,8;;XTextItem16:t(96,178)=(96,179)=s16chars:(96,180)=*(96,176),0,32;\nchars:(0,1),32,32;delta:(0,1),64,32;font:(97,8),96,32;;XEDataObject:t(96,181)=(96,182)=u4display:(96,89),0,32;gc:(96,13),0,32;\visual:(96,21),0,32;screen:(96,33),0,32;pixmap_format:(96,82),0,32;\font:(96,183)=*(96,170),0,32;;XFontSetExtents:t(96,184)=(96,185)=s16max_ink_extent:(96,60),0,64;\max_logical_extent:(96,60),64,64;;XOM:t(96,186)=(96,187)=*(96,188)=xs_XOM:XOC:t(96,189)=(96,190)=*(96,191)=xs_XOC:XFontSet:t(96,192)=(96,190)XmbTextItem:t(96,193)=(96,194)=s16chars:(9,35),0,32;nchars:(0,1),32,32;\delta:(0,1),64,32;font_set:(96,192),96,32;;XwcTextItem:t(96,195)=(96,196)=s16chars:(96,197)=*(12,1),0,32;\nchars:(0,1),32,32;delta:(0,1),64,32;font_set:(96,192),96,32;;XOMCharSetList:t(96,198)=(96,199)=s8charset_count:(0,1),0,32;\charset_list:(62,2),32,32;; :T(96,200)=eXOMOrientation_LTR_TTB:0,XOMOrientation_RTL_TTB:1,\XOrientation:t(96,201)=(96,200)XOMOrientation:t(96,202)=(96,203)=s8num_orientation:(0,1),0,32;\orientation:(96,204)=*(96,201),32,32;;XOMFontInfo:t(96,205)=(96,206)=s12num_font:(0,1),0,32;font_struct_list:(96,207)=*(96,183),32,32;\font_name_list:(62,2),64,32;;XIM:t(96,208)=(96,209)=*(96,210)=xs_XIM:XIC:t(96,211)=(96,212)=*(96,213)=xs_XIC:XIMProc:t(96,214)=(96,215)=*(96,216)=f(0,19)XICProc:t(96,217)=(96,218)=*(96,219)=f(0,1)XIDProc:t(96,220)=(96,221)=*(96,222)=f(0,19)XIMStyle:t(96,223)=(0,5)XIMStyles:t(96,224)=(96,225)=s8count_styles:(0,9),0,16;\supported_styles:(96,226)=*(96,223),32,32;;XVaNestedList:t(96,227)=(8,2)XIMCallback:t(96,228)=(96,229)=s8client_data:(96,1),0,32;\callback:(96,214),32,32;;XICCallback:t(96,230)=(96,231)=s8client_data:(96,1),0,32;\callback:(96,217),32,32;;XIMFeedback:t(96,232)=(0,5)_XIMText:T(96,233)=s16length:(0,9),0,16;feedback:(96,234)=*(96,232),32,32;\encoding_is_wchar:(0,1),64,32;string:(96,235)=u4multi_byte:(9,35),0,32;\wide_char:(96,197),0,32;;,96,32;;XIMText:t(96,236)=(96,233)XIMPreeditState:t(96,237)=(0,5)_XIMPreeditStateNotifyCallbackStruct:T(96,238)=s4state:(96,237),0,32;;XIMPreeditStateNotifyCallbackStruct:t(96,239)=(96,238)XIMResetState:t(96,240)=(0,5)XIMStringConversionFeedback:t(96,241)=(0,5)_XIMStringConversionText:T(96,242)=s16length:(0,9),0,16;\feedback:(96,243)=*(96,241),32,32;encoding_is_wchar:(0,1),64,32;\string:(96,244)=u4mbs:(9,35),0,32;wcs:(96,197),0,32;;,96,32;;XIMStringConversionText:t(96,245)=(96,242)XIMStringConversionPosition:t(96,246)=(0,9)XIMStringConversionType:t(96,247)=(0,9)XIMStringConversionOperation:t(96,248)=(0,9) :T(96,249)=eXIMForwardChar:0,XIMBackwardChar:1,XIMForwardWord:2,\XIMCaretDirection:t(96,250)=(96,249)_XIMStringConversionCallbackStruct:T(96,251)=s16position:(96,246),0,16;\direction:(96,250),32,32;operation:(96,248),64,16;\factor:(0,9),80,16;text:(96,252)=*(96,245),96,32;;XIMStringConversionCallbackStruct:t(96,253)=(96,251)_XIMPreeditDrawCallbackStruct:T(96,254)=s16caret:(0,1),0,32;\text:(96,255)=*(96,236),96,32;;XIMPreeditDrawCallbackStruct:t(96,256)=(96,254) :T(96,257)=eXIMIsInvisible:0,XIMIsPrimary:1,XIMIsSecondary:2,;XIMCaretStyle:t(96,258)=(96,257)_XIMPreeditCaretCallbackStruct:T(96,259)=s12position:(0,1),0,32;\direction:(96,250),32,32;style:(96,258),64,32;;XIMPreeditCaretCallbackStruct:t(96,260)=(96,259) :T(96,261)=eXIMTextType:0,XIMBitmapType:1,;XIMStatusDataType:t(96,262)=(96,261)_XIMStatusDrawCallbackStruct:T(96,263)=s8type:(96,262),0,32;\data:(96,264)=u4text:(96,255),0,32;bitmap:(97,9),0,32;;,32,32;;XIMStatusDrawCallbackStruct:t(96,265)=(96,263)_XIMHotKeyTrigger:T(96,266)=s12keysym:(97,13),0,32;modifier:(0,1),32,32;\XIMHotKeyTrigger:t(96,267)=(96,266)_XIMHotKeyTriggers:T(96,268)=s8num_hot_key:(0,1),0,32;\key:(96,269)=*(96,267),32,32;;XIMHotKeyTriggers:t(96,270)=(96,268)XIMHotKeyState:t(96,271)=(0,5)XIMValuesList:t(96,272)=(96,273)=s8count_values:(0,9),0,16;\supported_values:(62,2),32,32;;XErrorHandler:t(96,274)=(96,275)=*(96,276)=f(0,1)XIOErrorHandler:t(96,277)=(96,278)=*(96,279)=f(0,1)XConnectionWatchProc:t(96,280)=(96,281)=*(96,282)=f(0,19)Tk_BindingTable:t(95,1)=(95,2)=*(95,3)=xsTk_BindingTable_:Tk_Canvas:t(95,4)=(95,5)=*(95,6)=xsTk_Canvas_:Tk_Cursor:t(95,7)=(95,8)=*(95,9)=xsTk_Cursor_:Tk_ErrorHandler:t(95,10)=(95,11)=*(95,12)=xsTk_ErrorHandler_:Tk_Font:t(95,13)=(95,14)=*(95,15)=xsTk_Font_:Tk_Image:t(95,16)=(95,17)=*(95,18)=xsTk_Image__:Tk_ImageMaster:t(95,19)=(95,20)=*(95,21)=xsTk_ImageMaster_:Tk_TextLayout:t(95,22)=(95,23)=*(95,24)=xsTk_TextLayout_:Tk_Window:t(95,25)=(95,26)=*(95,27)=xsTk_Window_:Tk_3DBorder:t(95,28)=(95,29)=*(95,30)=xsTk_3DBorder_:Tk_Uid:t(95,31)=(9,35)Tk_ArgvInfo:t(95,32)=(95,33)=s20key:(9,35),0,32;type:(0,1),32,32;\Tk_OptionParseProc:t(95,34)=(95,35)=f(0,1)Tk_OptionPrintProc:t(95,36)=(95,37)=f(9,35)Tk_CustomOption:T(95,38)=s12parseProc:(95,39)=*(95,34),0,32;\printProc:(95,40)=*(95,36),32,32;clientData:(94,1),64,32;;Tk_CustomOption:t(95,41)=(95,38)Tk_ConfigSpec:T(95,42)=s32type:(0,1),0,32;argvName:(9,35),32,32;\offset:(0,1),160,32;specFlags:(0,1),192,32;customPtr:(95,43)=*(95,41),224,32;;Tk_ConfigSpec:t(95,44)=(95,42) :T(95,45)=eTK_DEFER_EVENT:0,TK_PROCESS_EVENT:1,\Tk_RestrictAction:t(95,46)=(95,45) :T(95,47)=eTK_ANCHOR_N:0,TK_ANCHOR_NE:1,TK_ANCHOR_E:2,\Tk_Anchor:t(95,48)=(95,47) :T(95,49)=eTK_JUSTIFY_LEFT:0,TK_JUSTIFY_RIGHT:1,\Tk_Justify:t(95,50)=(95,49)Tk_FontMetrics:T(95,51)=s12ascent:(0,1),0,32;descent:(0,1),32,32;\Tk_FontMetrics:t(95,52)=(95,51)Tk_GeomRequestProc:t(95,53)=(95,54)=f(0,19)Tk_GeomLostSlaveProc:t(95,55)=(95,54)Tk_GeomMgr:T(95,56)=s12name:(9,35),0,32;requestProc:(95,57)=*(95,53),32,32;\lostSlaveProc:(95,58)=*(95,55),64,32;;Tk_GeomMgr:t(95,59)=(95,56)XVirtualEvent:t(95,60)=(95,61)=s60type:(0,1),0,32;serial:(0,5),32,32;\event:(97,6),128,32;root:(97,6),160,32;subwindow:(97,6),192,32;\name:(95,31),416,32;same_screen:(0,1),448,32;;XActivateDeactivateEvent:t(95,62)=(95,63)=s20type:(0,1),0,32;\XActivateEvent:t(95,64)=(95,62)XDeactivateEvent:t(95,65)=(95,62)Tk_FakeWin:T(95,66)=s216display:(96,89),0,32;dummy1:(9,35),32,32;\screenNum:(0,1),64,32;visual:(96,21),96,32;depth:(0,1),128,32;\window:(97,6),160,32;dummy2:(9,35),192,32;dummy3:(9,35),224,32;\parentPtr:(95,25),256,32;dummy4:(9,35),288,32;dummy5:(9,35),320,32;\pathName:(9,35),352,32;nameUid:(95,31),384,32;classUid:(95,31),416,32;\changes:(96,52),448,224;dummy6:(0,4),672,32;atts:(96,29),704,480;\dummy9:(96,211),1280,32;dummy10:(95,67)=*(94,1),1312,32;\dummy14:(9,35),1440,32;dummy15:(94,1),1472,32;reqWidth:(0,1),1504,32;\dummy16:(9,35),1600,32;dummy17:(9,35),1632,32;dummy18:(94,1),1664,32;\Tk_FakeWin:t(95,68)=(95,66)Tk_Item:T(95,69)=s52id:(0,1),0,32;nextPtr:(95,70)=*(95,69),32,32;\staticTagSpace:(95,71)=ar(0,0);0;2;(95,31),64,96;tagPtr:(95,72)=*(95,31),160,32;\tagSpace:(0,1),192,32;numTags:(0,1),224,32;typePtr:(95,73)=*(95,74)=xsTk_ItemType:,256,32;\Tk_Item:t(95,75)=(95,69)Tk_ItemCreateProc:t(95,76)=(95,77)=f(0,1)Tk_ItemConfigureProc:t(95,78)=(95,79)=f(0,1)Tk_ItemCoordProc:t(95,80)=(95,77)Tk_ItemDeleteProc:t(95,81)=(95,82)=f(0,19)Tk_ItemDisplayProc:t(95,83)=(95,84)=f(0,19)Tk_ItemPointProc:t(95,85)=(95,86)=f(0,13)Tk_ItemAreaProc:t(95,87)=(95,88)=f(0,1)Tk_ItemPostscriptProc:t(95,89)=(95,90)=f(0,1)Tk_ItemScaleProc:t(95,91)=(95,92)=f(0,19)Tk_ItemTranslateProc:t(95,93)=(95,94)=f(0,19)Tk_ItemIndexProc:t(95,95)=(95,96)=f(0,1)Tk_ItemCursorProc:t(95,97)=(95,98)=f(0,19)Tk_ItemSelectionProc:t(95,99)=(95,100)=f(0,1)Tk_ItemInsertProc:t(95,101)=(95,102)=f(0,19)Tk_ItemDCharsProc:t(95,103)=(95,104)=f(0,19)Tk_ItemType:T(95,74)=s80name:(9,35),0,32;itemSize:(0,1),32,32;\createProc:(95,105)=*(95,76),64,32;configSpecs:(95,106)=*(95,44),96,32;\configProc:(95,107)=*(95,78),128,32;coordProc:(95,108)=*(95,80),160,32;\deleteProc:(95,109)=*(95,81),192,32;displayProc:(95,110)=*(95,83),224,32;\alwaysRedraw:(0,1),256,32;pointProc:(95,111)=*(95,85),288,32;\areaProc:(95,112)=*(95,87),320,32;postscriptProc:(95,113)=*(95,89),352,32;\scaleProc:(95,114)=*(95,91),384,32;translateProc:(95,115)=*(95,93),416,32;\indexProc:(95,116)=*(95,95),448,32;icursorProc:(95,117)=*(95,97),480,32;\selectionProc:(95,118)=*(95,99),512,32;insertProc:(95,119)=*(95,101),544,32;\dCharsProc:(95,120)=*(95,103),576,32;nextPtr:(95,73),608,32;;Tk_ItemType:t(95,121)=(95,74)Tk_CanvasTextInfo:T(95,122)=s56selBorder:(95,28),0,32;selBorderWidth:(0,1),32,32;\selFgColorPtr:(95,123)=*(96,54),64,32;selItemPtr:(95,124)=*(95,75),96,32;\anchorItemPtr:(95,124),192,32;selectAnchor:(0,1),224,32;\insertBorder:(95,28),256,32;insertWidth:(0,1),288,32;\insertBorderWidth:(0,1),320,32;focusItemPtr:(95,124),352,32;\Tk_CanvasTextInfo:t(95,125)=(95,122)Tk_ImageType:t(95,126)=(95,127)=xsTk_ImageType:Tk_ImageCreateProc:t(95,128)=(95,129)=f(0,1)Tk_ImageGetProc:t(95,130)=(95,131)=f(94,1)Tk_ImageDisplayProc:t(95,132)=(95,133)=f(0,19)Tk_ImageFreeProc:t(95,134)=(95,135)=f(0,19)Tk_ImageDeleteProc:t(95,136)=(94,43)Tk_ImageChangedProc:t(95,137)=(95,138)=f(0,19)Tk_ImageType:T(95,127)=s28name:(9,35),0,32;createProc:(95,139)=*(95,128),32,32;\getProc:(95,140)=*(95,130),64,32;displayProc:(95,141)=*(95,132),96,32;\freeProc:(95,142)=*(95,134),128,32;deleteProc:(95,143)=*(95,136),160,32;\nextPtr:(95,144)=*(95,127),192,32;;Tk_PhotoHandle:t(95,145)=(8,2)Tk_PhotoImageBlock:T(95,146)=s32pixelPtr:(95,147)=*(0,11),0,32;\pixelSize:(0,1),128,32;offset:(95,148)=ar(0,0);0;2;(0,1),160,96;;Tk_PhotoImageBlock:t(95,149)=(95,146)Tk_PhotoImageFormat:t(95,150)=(95,151)=xsTk_PhotoImageFormat:Tk_ImageFileMatchProc:t(95,152)=(95,153)=f(0,1)Tk_ImageStringMatchProc:t(95,154)=(95,155)=f(0,1)Tk_ImageFileReadProc:t(95,156)=(95,157)=f(0,1)Tk_ImageStringReadProc:t(95,158)=(95,159)=f(0,1)Tk_ImageFileWriteProc:t(95,160)=(95,161)=f(0,1)Tk_ImageStringWriteProc:t(95,162)=(95,163)=f(0,1)Tk_PhotoImageFormat:T(95,151)=s32name:(9,35),0,32;fileMatchProc:(95,164)=*(95,152),32,32;\stringMatchProc:(95,165)=*(95,154),64,32;fileReadProc:(95,166)=*(95,156),96,32;\stringReadProc:(95,167)=*(95,158),128,32;fileWriteProc:(95,168)=*(95,160),160,32;\stringWriteProc:(95,169)=*(95,162),192,32;nextPtr:(95,170)=*(95,151),224,32;;Tk_ErrorProc:t(95,171)=(95,172)=f(0,1)Tk_EventProc:t(95,173)=(95,174)=f(0,19)Tk_GenericProc:t(95,175)=(95,176)=f(0,1)Tk_GetSelProc:t(95,177)=(95,178)=f(0,1)Tk_LostSelProc:t(95,179)=(94,43)Tk_RestrictProc:t(95,180)=(95,181)=f(95,46)Tk_SelectionProc:t(95,182)=(95,183)=f(0,1)/usr/include/malloc.hmallinfo:T(102,1)=s40arena:(0,1),0,32;ordblks:(0,1),32,32;\smblks:(0,1),64,32;hblks:(0,1),96,32;hblkhd:(0,1),128,32;\usmblks:(0,1),160,32;fsmblks:(0,1),192,32;uordblks:(0,1),224,32;\fordblks:(0,1),256,32;keepcost:(0,1),288,32;;/usr/include/fcntl.h/usr/include/bits/fcntl.hflock:T(105,1)=s16l_type:(0,8),0,16;l_whence:(0,8),16,16;\l_start:(9,23),32,32;l_len:(9,23),64,32;l_pid:(9,25),96,32;;/usr/include/errno.h/usr/include/bits/errno.h/usr/include/linux/errno.h/usr/include/asm/errno.h/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/unistd.h/usr/include/bits/posix_opt.h/usr/include/bits/confname.h :T(113,1)=e_PC_LINK_MAX:0,_PC_MAX_CANON:1,_PC_MAX_INPUT:2,\_PC_NAME_MAX:3,_PC_PATH_MAX:4,_PC_PIPE_BUF:5,\_PC_CHOWN_RESTRICTED:6,_PC_NO_TRUNC:7,_PC_VDISABLE:8,\_PC_SYNC_IO:9,_PC_ASYNC_IO:10,_PC_PRIO_IO:11,\_PC_SOCK_MAXBUF:12,; :T(113,2)=e_SC_ARG_MAX:0,_SC_CHILD_MAX:1,_SC_CLK_TCK:2,\_SC_NGROUPS_MAX:3,_SC_OPEN_MAX:4,_SC_STREAM_MAX:5,\_SC_TZNAME_MAX:6,_SC_JOB_CONTROL:7,_SC_SAVED_IDS:8,\_SC_REALTIME_SIGNALS:9,_SC_PRIORITY_SCHEDULING:10,\_SC_TIMERS:11,_SC_ASYNCHRONOUS_IO:12,_SC_PRIORITIZED_IO:13,\_SC_SYNCHRONIZED_IO:14,_SC_FSYNC:15,_SC_MAPPED_FILES:16,\_SC_MEMLOCK:17,_SC_MEMLOCK_RANGE:18,_SC_MEMORY_PROTECTION:19,\_SC_MESSAGE_PASSING:20,_SC_SEMAPHORES:21,_SC_SHARED_MEMORY_OBJECTS:22,\_SC_AIO_LISTIO_MAX:23,_SC_AIO_MAX:24,_SC_AIO_PRIO_DELTA_MAX:25,\_SC_DELAYTIMER_MAX:26,_SC_MQ_OPEN_MAX:27,_SC_MQ_PRIO_MAX:28,\_SC_VERSION:29,_SC_PAGESIZE:30,_SC_RTSIG_MAX:31,\_SC_SEM_NSEMS_MAX:32,_SC_SEM_VALUE_MAX:33,_SC_SIGQUEUE_MAX:34,\_SC_TIMER_MAX:35,_SC_BC_BASE_MAX:36,_SC_BC_DIM_MAX:37,\_SC_BC_SCALE_MAX:38,_SC_BC_STRING_MAX:39,_SC_COLL_WEIGHTS_MAX:40,\_SC_EQUIV_CLASS_MAX:41,_SC_EXPR_NEST_MAX:42,_SC_LINE_MAX:43,\_SC_RE_DUP_MAX:44,_SC_CHARCLASS_NAME_MAX:45,_SC_2_VERSION:46,\_SC_2_C_BIND:47,_SC_2_C_DEV:48,_SC_2_FORT_DEV:49,\_SC_2_FORT_RUN:50,_SC_2_SW_DEV:51,_SC_2_LOCALEDEF:52,\_SC_PII:53,_SC_PII_XTI:54,_SC_PII_SOCKET:55,\_SC_PII_INTERNET:56,_SC_PII_OSI:57,_SC_POLL:58,\_SC_SELECT:59,_SC_UIO_MAXIOV:60,_SC_PII_INTERNET_STREAM:61,\_SC_PII_INTERNET_DGRAM:62,_SC_PII_OSI_COTS:63,_SC_PII_OSI_CLTS:64,\_SC_PII_OSI_M:65,_SC_T_IOV_MAX:66,_SC_THREADS:67,\_SC_THREAD_SAFE_FUNCTIONS:68,_SC_GETGR_R_SIZE_MAX:69,\_SC_GETPW_R_SIZE_MAX:70,_SC_LOGIN_NAME_MAX:71,_SC_TTY_NAME_MAX:72,\_SC_THREAD_DESTRUCTOR_ITERATIONS:73,_SC_THREAD_KEYS_MAX:74,\_SC_THREAD_STACK_MIN:75,_SC_THREAD_THREADS_MAX:76,\_SC_THREAD_ATTR_STACKADDR:77,_SC_THREAD_ATTR_STACKSIZE:78,\_SC_THREAD_PRIORITY_SCHEDULING:79,_SC_THREAD_PRIO_INHERIT:80,\_SC_THREAD_PRIO_PROTECT:81,_SC_THREAD_PROCESS_SHARED:82,\_SC_NPROCESSORS_CONF:83,_SC_NPROCESSORS_ONLN:84,_SC_PHYS_PAGES:85,\_SC_AVPHYS_PAGES:86,_SC_ATEXIT_MAX:87,_SC_PASS_MAX:88,\_SC_XOPEN_VERSION:89,_SC_XOPEN_XCU_VERSION:90,_SC_XOPEN_UNIX:91,\_SC_XOPEN_CRYPT:92,_SC_XOPEN_ENH_I18N:93,_SC_XOPEN_SHM:94,\_SC_2_CHAR_TERM:95,_SC_2_C_VERSION:96,_SC_2_UPE:97,\_SC_XOPEN_XPG2:98,_SC_XOPEN_XPG3:99,_SC_XOPEN_XPG4:100,\_SC_CHAR_BIT:101,_SC_CHAR_MAX:102,_SC_CHAR_MIN:103,\_SC_INT_MAX:104,_SC_INT_MIN:105,_SC_LONG_BIT:106,\_SC_WORD_BIT:107,_SC_MB_LEN_MAX:108,_SC_NZERO:109,\_SC_SSIZE_MAX:110,_SC_SCHAR_MAX:111,_SC_SCHAR_MIN:112,\_SC_SHRT_MAX:113,_SC_SHRT_MIN:114,_SC_UCHAR_MAX:115,\_SC_UINT_MAX:116,_SC_ULONG_MAX:117,_SC_USHRT_MAX:118,\_SC_NL_ARGMAX:119,_SC_NL_LANGMAX:120,_SC_NL_MSGMAX:121,\_SC_NL_NMAX:122,_SC_NL_SETMAX:123,_SC_NL_TEXTMAX:124,\_SC_XBS5_ILP32_OFF32:125,_SC_XBS5_ILP32_OFFBIG:126,\_SC_XBS5_LP64_OFF64:127,_SC_XBS5_LPBIG_OFFBIG:128,_SC_XOPEN_LEGACY:129,\_SC_XOPEN_REALTIME:130,_SC_XOPEN_REALTIME_THREADS:131,; :T(113,3)=e_CS_PATH:0,;advert_data:T(1,1)=s60interval:(0,4),0,32;end_time:(0,5),32,32;\aid:(9,35),64,32;data:(9,35),96,32;tx_sock:(0,1),128,32;\authinfo:(1,2)=*(1,3)=xsauth_info:,160,32;sap_hdr:(1,4)=*(1,5)=xssap_header:,192,32;\sapenc_p:(1,6)=*(1,7)=xspriv_header:,224,32;ttl:(0,11),256,8;\padding:(0,4),288,32;length:(0,4),320,32;encrypt:(0,1),352,32;\next_ad:(1,8)=*(1,1),384,32;prev_ad:(1,8),416,32;\timer_token:(94,23),448,32;;sap_header:T(1,5)=s8compress:(17,3),0,1;enc:(17,3),1,1;\type:(17,3),2,3;version:(17,3),5,3;authlen:(17,3),8,8;\msgid:(17,3),16,16;src:(17,3),32,32;;auth_info:T(1,3)=s40auth_type:(17,3),0,32;padding:(17,3),32,32;\version:(17,3),64,32;siglen:(17,3),96,32;autlen:(17,3),128,32;\pad_len:(17,3),160,32;sig_len:(17,3),192,32;key_len:(17,3),224,32;\signature:(9,35),256,32;keycertificate:(9,35),288,32;;auth_header:T(1,9)=s4auth_type:(17,3),0,4;padding:(17,3),4,1;\version:(17,3),5,3;siglen:(17,3),8,8;;priv_header:T(1,7)=s24enc_type:(17,3),0,4;padding:(17,3),4,1;\version:(17,3),5,3;hdr_len:(17,3),8,8;pad_len:(17,3),32,32;\txt_len:(17,3),64,32;encd_len:(17,3),96,32;enc_data:(9,35),128,32;\txt_data:(9,35),160,32;;enc_header:T(1,10)=s4timeout:(17,3),0,32;;hash_t:t(1,11)=(0,4)lsdap_header:T(1,12)=s4check:(17,1),0,8;type:(17,1),8,8;\payload:(10,5),16,8;;lsdap_advert:T(1,13)=s12check:(17,1),0,8;type:(17,1),8,8;\origin:(17,1),16,8;ttl:(17,1),24,8;hash:(1,11),32,32;\addata:(10,5),64,8;;lsdap_hashlist:T(1,14)=s8check:(17,1),0,8;type:(17,1),8,8;\seq:(17,1),16,8;padding2:(17,1),24,8;hashlist:(1,15)=ar(0,0);0;0;(1,11),32,32;;lsdap_hashreq:T(1,16)=s8check:(17,1),0,8;type:(17,1),8,8;\padding1:(17,1),16,8;padding2:(17,1),24,8;hash:(1,11),32,32;;../src/prototypes.h../src/generic_prototypes.h../src/www_prototypes.hbus_recv:F(0,1)length:r(0,1)buf:V(0,20)=ar(0,0);0;2047;(0,2)from:(40,10)fromlen:(0,1)bus_send:F(0,1)msg:P(9,35)len:P(0,1)ttl:(0,11)bustxsock:r(0,1)sin:(40,10)bus_listen:F(0,1)is_a_bus_message:F(0,1)buf:P(9,35)parse_bus_message:F(0,19)line:r(9,35)__nptr:r(68,3)addrstr:(39,11)bus_send_new_app:F(0,1)display:r(9,35)msg:(92,4)pid:r(17,16)../src/compat.cstrerror:F(0,20)=*(0,2)i:P(0,1)msg:V(0,21)=ar(0,0);0;99;(0,2)../src/generate_ids.c../src/generate_ids.haddr_list:T(115,1)=s16addr:(40,3),0,32;endtime:(0,5),32,32;\next:(115,2)=*(115,1),64,32;prev:(115,2),96,32;;generate_port:F(0,1)media:P(9,35)base:r(0,1)mask:r(0,1)first_addr:S(115,2)last_addr:S(115,2)store_address:F(0,1)addr:P(0,20)=*(40,3)endtime:P(0,5)new_address:r(115,2)delete_address:F(0,1)test:P(115,2)check_address:F(0,1)addr:P(0,20)test:r(115,2)tmp:r(115,2)tv:(70,1)generate_address:F(40,3)baseaddr:P(0,20)netmask:P(0,1)newaddr:(40,3)mask:r(40,3)xx:r(0,5)../src/iohandler.clinksocket:F(0,19)fd:P(0,1)mask:P(0,1)callback:P(0,20)=*(2,58)unlinksocket:F(0,19)../src/random.c../src/sap_crypt.hkeydata:T(115,1)=s532key:(92,4),0,2048;keyname:(92,4),2048,2048;\keyversion:(17,3),4096,32;starttime:(17,3),4128,32;\endtime:(17,3),4160,32;prev:(115,2)=*(115,1),4192,32;\next:(115,2),4224,32;;keyfile:T(115,3)=s524key:(92,4),0,2048;keyname:(92,4),2048,2048;\endtime:(17,3),4160,32;;randseed:S(0,1)srandom:F(0,19)seed:P(0,4)random:F(17,27)x:r(0,1)hi:r(0,1)lo:r(0,1)t:r(0,3)seeded:S(0,1)sec_randomkey:F(0,1)key:P(9,35)seed:P(0,20)=*(0,1)temp_key:(0,21)=s8no:(0,22)=ar(0,0);0;1;(0,3),0,64;;sec_seed:F(0,1)sec_longrand:F(0,3)../src/sd_listen.c/usr/arm-linuxelf/include/assert.h/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/locale.hlconv:T(2,1)=s48decimal_point:(2,2)=*(0,2),0,32;thousands_sep:(2,2),32,32;\grouping:(2,2),64,32;int_curr_symbol:(2,2),96,32;\currency_symbol:(2,2),128,32;mon_decimal_point:(2,2),160,32;\mon_thousands_sep:(2,2),192,32;mon_grouping:(2,2),224,32;\positive_sign:(2,2),256,32;negative_sign:(2,2),288,32;\/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/signal.h__caddr_t:t(9,34)=(2,2)__time_t:t(9,35)=(0,3)__swblk_t:t(9,36)=(0,3)__clock_t:t(9,37)=(0,3)__fd_mask:t(9,38)=(0,5)__fd_set:t(9,39)=(9,40)=s128fds_bits:(9,41)=ar(0,0);0;31;(9,38),0,1024;;__key_t:t(9,42)=(0,1)__ipc_pid_t:t(9,43)=(0,9)__blkcnt_t:t(9,44)=(9,4)__blkcnt64_t:t(9,45)=(9,5)__fsblkcnt_t:t(9,46)=(0,3)__fsblkcnt64_t:t(9,47)=(9,6)__fsfilcnt_t:t(9,48)=(9,4)__fsfilcnt64_t:t(9,49)=(9,5)__ino64_t:t(9,50)=(9,4)__off64_t:t(9,51)=(9,24)__t_scalar_t:t(9,52)=(0,1)__t_uscalar_t:t(9,53)=(0,4)/usr/include/bits/sigset.h__sig_atomic_t:t(10,1)=(0,1)__sigset_t:t(10,2)=(10,3)=s128__val:(10,4)=ar(0,0);0;31;(0,5),0,1024;;sig_atomic_t:t(8,1)=(10,1)/usr/include/bits/signum.h__sighandler_t:t(8,2)=(8,3)=*(8,4)=f(0,19)sig_t:t(8,5)=(8,2)sigset_t:t(8,6)=(10,2)/usr/include/bits/siginfo.hsigval:T(13,1)=u4sival_int:(0,1),0,32;sival_ptr:(13,2)=*(0,19),0,32;;sigval_t:t(13,3)=(13,1)siginfo:T(13,4)=s128si_signo:(0,1),0,32;si_errno:(0,1),32,32;\si_code:(0,1),64,32;_sifields:(13,5)=u116_pad:(13,6)=ar(0,0);0;28;(0,1),0,928;\_kill:(13,7)=s8si_pid:(9,25),0,32;si_uid:(9,18),32,32;;,0,64;\_timer:(13,8)=s8_timer1:(0,4),0,32;_timer2:(0,4),32,32;;,0,64;\_rt:(13,9)=s12si_pid:(9,25),0,32;si_uid:(9,18),32,32;\si_sigval:(13,3),64,32;;,0,96;_sigchld:(13,10)=s16si_pid:(9,25),0,32;\si_status:(0,1),32,32;si_utime:(9,37),64,32;\si_stime:(9,37),96,32;;,0,128;_sigfault:(13,11)=s4si_addr:(13,2),0,32;;,0,32;\_sigpoll:(13,12)=s8si_band:(0,1),0,32;si_fd:(0,1),32,32;;,0,64;;,96,928;;siginfo_t:t(13,13)=(13,4) :T(13,14)=eSI_ASYNCIO:-4,SI_MESGQ:-3,SI_TIMER:-2,\SI_QUEUE:-1,SI_USER:0,; :T(13,15)=eILL_ILLOPC:1,ILL_ILL_OPN:2,ILL_ILLADR:3,\ILL_ILLTRP:4,ILL_PRVOPC:5,ILL_PRVREG:6,\ILL_COPROC:7,ILL_BADSTK:8,; :T(13,16)=eFPE_INTDIV:1,FPE_INTOVF:2,FPE_FLTDIV:3,\FPE_FLTOVF:4,FPE_FLTUND:5,FPE_FLTRES:6,\FPE_FLTINV:7,FPE_FLTSUB:8,; :T(13,17)=eSEGV_MAPERR:1,SEGV_ACCERR:2,; :T(13,18)=eBUS_ADRALN:1,BUS_ADRERR:2,BUS_OBJERR:3,; :T(13,19)=eTRAP_BRKPT:1,TRAP_TRACE:2,; :T(13,20)=eCLD_EXITED:1,CLD_KILLED:2,CLD_DUMPED:3,\CLD_TRAPPED:4,CLD_STOPPED:5,CLD_CONTINUED:6,; :T(13,21)=ePOLL_IN:1,POLL_OUT:2,POLL_MSG:3,\POLL_ERR:4,POLL_PRI:5,POLL_HUP:6,;sigevent:T(13,22)=s64sigev_value:(13,3),0,32;sigev_signo:(0,1),32,32;\sigev_notify:(0,1),64,32;_sigev_un:(13,23)=u52_pad:(13,24)=ar(0,0);0;12;(0,1),0,416;\_sigev_thread:(13,25)=s8_function:(13,26)=*(13,27)=f(0,19),0,32;\_attribute:(13,2),32,32;;,0,64;;,96,416;;sigevent_t:t(13,28)=(13,22) :T(13,29)=eSIGEV_SIGNAL:0,SIGEV_NONE:1,SIGEV_THREAD:2,;/usr/include/bits/sigaction.hsigaction:T(14,1)=s140__sigaction_handler:(14,2)=u4sa_handler:(8,2),0,32;\sa_sigaction:(14,3)=*(14,4)=f(0,19),0,32;;,0,32;\sa_mask:(10,2),32,1024;sa_flags:(0,1),1056,32;sa_restorer:(14,5)=*(14,6)=f(0,19),1088,32;;sigvec:T(8,7)=s12sv_handler:(8,2),0,32;sv_mask:(0,1),32,32;\sv_flags:(0,1),64,32;;/usr/include/bits/sigcontext.h/usr/include/asm/sigcontext.h/usr/include/asm/ptrace.h/usr/include/asm/proc/ptrace.hpt_regs:T(18,1)=s72uregs:(18,2)=ar(0,0);0;17;(0,3),0,576;;sigcontext:T(16,1)=s88magic:(0,5),0,32;reg:(18,1),32,576;\trap_no:(0,5),608,32;error_code:(0,5),640,32;\oldmask:(0,5),672,32;;/usr/include/bits/sigstack.hsigstack:T(20,1)=s8ss_sp:(13,2),0,32;ss_onstack:(0,1),32,32;;sigaltstack:T(20,2)=s12ss_sp:(13,2),0,32;ss_flags:(0,1),32,32;\ss_size:(19,1),64,32;;stack_t:t(20,3)=(20,2)ssize_t:t(21,1)=(9,26)u_char:t(28,1)=(9,1)u_short:t(28,2)=(9,2)u_int:t(28,3)=(9,3)u_long:t(28,4)=(9,4)quad_t:t(28,5)=(9,6)u_quad_t:t(28,6)=(9,5)fsid_t:t(28,7)=(9,30)loff_t:t(28,8)=(9,24)ino_t:t(28,9)=(9,20)dev_t:t(28,10)=(9,17)gid_t:t(28,11)=(9,19)mode_t:t(28,12)=(9,21)nlink_t:t(28,13)=(9,22)uid_t:t(28,14)=(9,18)off_t:t(28,15)=(9,23)pid_t:t(28,16)=(9,25)id_t:t(28,17)=(9,29)daddr_t:t(28,18)=(9,33)caddr_t:t(28,19)=(9,34)key_t:t(28,20)=(9,42)time_t:t(29,1)=(9,35)ulong:t(28,21)=(0,5)ushort:t(28,22)=(0,9)uint:t(28,23)=(0,4)int8_t:t(28,24)=(0,10)int16_t:t(28,25)=(0,8)int32_t:t(28,26)=(0,1)int64_t:t(28,27)=(0,6)u_int8_t:t(28,28)=(0,11)u_int16_t:t(28,29)=(0,9)u_int32_t:t(28,30)=(0,4)u_int64_t:t(28,31)=(0,7)register_t:t(28,32)=(0,1)fd_mask:t(33,1)=(9,38)fd_set:t(33,2)=(9,39)blkcnt_t:t(28,33)=(9,44)fsblkcnt_t:t(28,34)=(9,46)fsfilcnt_t:t(28,35)=(9,48)stat:T(37,1)=s88st_dev:(9,17),0,64;__pad1:(0,9),64,16;\st_blocks:(9,44),416,32;st_atime:(9,35),448,32;\__unused1:(0,5),480,32;st_mtime:(9,35),512,32;\__unused2:(0,5),544,32;st_ctime:(9,35),576,32;\/usr/include/setjmp.h/usr/include/bits/setjmp.h__jmp_buf:t(39,1)=(39,2)=ar(0,0);0;21;(0,1)__jmp_buf_tag:T(38,1)=s220__jmpbuf:(39,1),0,704;__mask_was_saved:(0,1),704,32;\__saved_mask:(10,2),736,1024;;jmp_buf:t(38,2)=(38,3)=ar(0,0);0;0;(38,1)sigjmp_buf:t(38,4)=(38,2)__gnuc_va_list:t(44,1)=(13,2)_IO_lock_t:t(45,1)=(0,19)_IO_marker:T(45,2)=s12_next:(45,3)=*(45,2),0,32;_sbuf:(45,4)=*(42,2),32,32;\_IO_FILE:T(42,2)=s148_flags:(0,1),0,32;_IO_read_ptr:(2,2),32,32;\_IO_read_end:(2,2),64,32;_IO_read_base:(2,2),96,32;\_IO_write_base:(2,2),128,32;_IO_write_ptr:(2,2),160,32;\_IO_write_end:(2,2),192,32;_IO_buf_base:(2,2),224,32;\_IO_buf_end:(2,2),256,32;_IO_save_base:(2,2),288,32;\_IO_backup_base:(2,2),320,32;_IO_save_end:(2,2),352,32;\_markers:(45,3),384,32;_chain:(45,4),416,32;_fileno:(0,1),448,32;\_shortbuf:(45,5)=ar(0,0);0;0;(0,2),568,8;_lock:(45,6)=*(45,1),576,32;\_offset:(9,51),608,64;_unused2:(45,7)=ar(0,0);0;15;(0,1),672,512;;_IO_FILE:t(45,8)=(42,2)_IO_cookie_io_functions_t:t(45,9)=(45,10)=s16read:(45,11)=*(45,12)=f(9,26),0,32;\write:(45,13)=*(45,14)=f(9,26),32,32;seek:(45,15)=*(45,16)=f(9,23),64,32;\close:(45,17)=*(45,18)=f(0,1),96,32;;_IO_cookie_file:T(45,19)=s172file:(42,2),0,1184;vtable:(45,20)=*(0,19),1184,32;\cookie:(13,2),1216,32;io_functions:(45,9),1248,128;;div_t:t(50,1)=(50,2)=s8quot:(0,1),0,32;rem:(0,1),32,32;;ldiv_t:t(50,3)=(50,4)=s8quot:(0,3),0,32;rem:(0,3),32,32;;random_data:T(50,5)=s28fptr:(50,6)=*(28,26),0,32;rptr:(50,6),32,32;\state:(50,6),64,32;rand_type:(0,1),96,32;rand_deg:(0,1),128,32;\rand_sep:(0,1),160,32;end_ptr:(50,6),192,32;;drand48_data:T(50,7)=s24x:(50,8)=ar(0,0);0;2;(0,9),0,48;\a:(50,8),48,48;c:(0,9),96,16;old_x:(50,8),112,48;\__compar_fn_t:t(50,9)=(50,10)=*(50,11)=f(0,1)sockaddr_ipx:T(72,1)=s16sipx_family:(58,1),0,16;sipx_port:(28,29),16,16;\sipx_network:(28,30),32,32;sipx_node:(72,2)=ar(0,0);0;5;(0,11),64,48;\sipx_type:(28,28),112,8;sipx_zero:(0,11),120,8;;ipx_route_definition:T(72,3)=s16ipx_network:(0,5),0,32;\ipx_router_network:(0,5),32,32;ipx_router_node:(72,2),64,48;;ipx_route_definition:t(72,4)=(72,3)ipx_interface_definition:T(72,5)=s28ipx_network:(0,5),0,32;\ipx_device:(61,2),32,128;ipx_dlink_type:(0,11),160,8;\ipx_special:(0,11),168,8;ipx_node:(72,2),176,48;;ipx_interface_definition:t(72,6)=(72,5)ipx_config_data:T(72,7)=s4ipxcfg_auto_select_primary:(0,11),0,8;\ipx_config_data:t(72,8)=(72,7)ipx_route_def:T(72,9)=s32ipx_network:(0,5),0,32;ipx_router_network:(0,5),32,32;\ipx_router_node:(72,2),64,48;ipx_device:(61,2),112,128;\ :T(81,1)=eIFF_UP:1,IFF_BROADCAST:2,IFF_DEBUG:4,\ifaddr:T(81,2)=s40ifa_addr:(56,3),0,128;ifa_ifu:(81,3)=u16ifu_broadaddr:(56,3),0,128;\ifu_dstaddr:(56,3),0,128;;,128,128;ifa_ifp:(81,4)=*(81,5)=xsiface:,256,32;\ifa_next:(81,6)=*(81,2),288,32;;ifmap:T(81,7)=s16mem_start:(0,5),0,32;mem_end:(0,5),32,32;\ifreq:T(81,8)=s32ifr_ifrn:(81,9)=u16ifrn_name:(66,11),0,128;;,0,128;\ifr_ifru:(81,10)=u16ifru_addr:(56,3),0,128;ifru_dstaddr:(56,3),0,128;\ifru_broadaddr:(56,3),0,128;ifru_netmask:(56,3),0,128;\ifru_hwaddr:(56,3),0,128;ifru_flags:(0,8),0,16;\ifru_map:(81,7),0,128;ifru_slave:(66,11),0,128;\ifconf:T(81,11)=s8ifc_len:(0,1),0,32;ifc_ifcu:(81,12)=u4ifcu_buf:(9,34),0,32;\ifcu_req:(81,13)=*(81,8),0,32;;,32,32;;if_nameindex:T(81,14)=s8if_index:(0,4),0,32;if_name:(2,2),32,32;;rpcent:T(89,1)=s12r_name:(2,2),0,32;r_aliases:(89,2)=*(2,2),32,32;\hostent:T(88,1)=s20h_name:(2,2),0,32;h_aliases:(89,2),32,32;\h_addr_list:(89,2),128,32;;netent:T(88,2)=s16n_name:(2,2),0,32;n_aliases:(89,2),32,32;\servent:T(88,3)=s16s_name:(2,2),0,32;s_aliases:(89,2),32,32;\s_port:(0,1),64,32;s_proto:(2,2),96,32;;protoent:T(88,4)=s12p_name:(2,2),0,32;p_aliases:(89,2),32,32;\addrinfo:T(88,5)=s32ai_flags:(0,1),0,32;ai_family:(0,1),32,32;\ai_addrlen:(0,1),128,32;ai_addr:(54,5),160,32;\ai_canonname:(2,2),192,32;ai_next:(88,6)=*(88,5),224,32;;passwd:T(92,1)=s28pw_name:(2,2),0,32;pw_passwd:(2,2),32,32;\pw_uid:(9,18),64,32;pw_gid:(9,19),96,32;pw_gecos:(2,2),128,32;\pw_dir:(2,2),160,32;pw_shell:(2,2),192,32;;timeval:T(97,1)=s8tv_sec:(9,35),0,32;tv_usec:(9,35),32,32;;clock_t:t(95,1)=(9,37)tm:T(95,2)=s44tm_sec:(0,1),0,32;tm_min:(0,1),32,32;\tm_zone:(95,3)=*(0,2),320,32;;__res_state:T(117,1)=s512retrans:(0,1),0,32;retry:(0,1),32,32;\options:(28,4),64,32;nscount:(0,1),96,32;nsaddr_list:(117,2)=ar(0,0);0;2;(67,10),128,384;\id:(28,2),512,16;dnsrch:(117,3)=ar(0,0);0;6;(2,2),544,224;\defdname:(117,4)=ar(0,0);0;255;(0,2),768,2048;pfcode:(28,4),2816,32;\ndots:(0,4),2848,4;nsort:(0,4),2852,4;unused:(117,5)=ar(0,0);0;2;(0,2),2856,24;\sort_list:(117,6)=ar(0,0);0;9;(117,7)=s8addr:(67,3),0,32;\mask:(28,30),32,32;;,2880,640;pad:(117,8)=ar(0,0);0;71;(0,2),3520,576;; :T(117,9)=eres_goahead:0,res_nextns:1,res_modified:2,\res_sendhookact:t(117,10)=(117,9)res_send_qhook:t(117,11)=(117,12)=*(117,13)=f(117,10)res_send_rhook:t(117,14)=(117,15)=*(117,16)=f(117,10)res_sym:T(117,17)=s12number:(0,1),0,32;name:(2,2),32,32;\humanname:(2,2),64,32;;ClientData:t(119,1)=(13,2)Tcl_Interp:T(119,2)=s12result:(2,2),0,32;freeProc:(119,3)=*(119,4)=f(0,19),32,32;\Tcl_Interp:t(119,5)=(119,2)Tcl_AsyncHandler:t(119,6)=(119,7)=*(119,8)=xsTcl_AsyncHandler_:Tcl_Channel:t(119,9)=(119,10)=*(119,11)=xsTcl_Channel_:Tcl_Command:t(119,12)=(119,13)=*(119,14)=xsTcl_Command_:Tcl_Event:t(119,15)=(119,16)=xsTcl_Event:Tcl_Pid:t(119,17)=(119,18)=*(119,19)=xsTcl_Pid_:Tcl_RegExp:t(119,20)=(119,21)=*(119,22)=xsTcl_RegExp_:Tcl_TimerToken:t(119,23)=(119,24)=*(119,25)=xsTcl_TimerToken_:Tcl_Trace:t(119,26)=(119,27)=*(119,28)=xsTcl_Trace_:Tcl_Var:t(119,29)=(119,30)=*(119,31)=xsTcl_Var_: :T(119,32)=eTCL_INT:0,TCL_DOUBLE:1,TCL_EITHER:2,;Tcl_ValueType:t(119,33)=(119,32)Tcl_Value:T(119,34)=s16type:(119,33),0,32;intValue:(0,3),32,32;\Tcl_Value:t(119,35)=(119,34)Tcl_AppInitProc:t(119,36)=(119,37)=f(0,1)Tcl_AsyncProc:t(119,38)=(119,39)=f(0,1)Tcl_ChannelProc:t(119,40)=(119,41)=f(0,19)Tcl_CloseProc:t(119,42)=(119,43)=f(0,19)Tcl_CmdDeleteProc:t(119,44)=(119,43)Tcl_CmdProc:t(119,45)=(119,46)=f(0,1)Tcl_CmdTraceProc:t(119,47)=(119,48)=f(0,19)Tcl_DupInternalRepProc:t(119,49)=(119,50)=f(0,19)Tcl_EventProc:t(119,51)=(119,52)=f(0,1)Tcl_EventCheckProc:t(119,53)=(119,41)Tcl_EventDeleteProc:t(119,54)=(119,55)=f(0,1)Tcl_EventSetupProc:t(119,56)=(119,41)Tcl_ExitProc:t(119,57)=(119,43)Tcl_FileProc:t(119,58)=(119,41)Tcl_FileFreeProc:t(119,59)=(119,43)Tcl_FreeInternalRepProc:t(119,60)=(119,61)=f(0,19)Tcl_FreeProc:t(119,62)=(119,4)Tcl_IdleProc:t(119,63)=(119,43)Tcl_InterpDeleteProc:t(119,64)=(119,65)=f(0,19)Tcl_MathProc:t(119,66)=(119,67)=f(0,1)Tcl_NamespaceDeleteProc:t(119,68)=(119,43)Tcl_ObjCmdProc:t(119,69)=(119,70)=f(0,1)Tcl_PackageInitProc:t(119,71)=(119,37)Tcl_TcpAcceptProc:t(119,72)=(119,73)=f(0,19)Tcl_TimerProc:t(119,74)=(119,43)Tcl_SetFromAnyProc:t(119,75)=(119,76)=f(0,1)Tcl_UpdateStringProc:t(119,77)=(119,61)Tcl_VarTraceProc:t(119,78)=(119,79)=f(2,2)Tcl_ObjType:T(119,80)=s20name:(2,2),0,32;freeIntRepProc:(119,81)=*(119,60),32,32;\dupIntRepProc:(119,82)=*(119,49),64,32;updateStringProc:(119,83)=*(119,77),96,32;\setFromAnyProc:(119,84)=*(119,75),128,32;;Tcl_ObjType:t(119,85)=(119,80)Tcl_Obj:T(119,86)=s24refCount:(0,1),0,32;bytes:(2,2),32,32;\length:(0,1),64,32;typePtr:(119,87)=*(119,85),96,32;\internalRep:(119,88)=u8longValue:(0,3),0,32;doubleValue:(0,13),0,64;\otherValuePtr:(13,2),0,32;twoPtrValue:(119,89)=s8ptr1:(13,2),0,32;\ptr2:(13,2),32,32;;,0,64;;,128,64;;Tcl_Obj:t(119,90)=(119,86)Tcl_Namespace:T(119,91)=s20name:(2,2),0,32;fullName:(2,2),32,32;\clientData:(119,1),64,32;deleteProc:(119,92)=*(119,68),96,32;\parentPtr:(119,93)=*(119,91),128,32;;Tcl_Namespace:t(119,94)=(119,91)Tcl_CallFrame:T(119,95)=s44nsPtr:(119,96)=*(119,94),0,32;dummy1:(0,1),32,32;\dummy2:(0,1),64,32;dummy3:(2,2),96,32;dummy4:(2,2),128,32;\dummy5:(2,2),160,32;dummy6:(0,1),192,32;dummy7:(2,2),224,32;\dummy8:(2,2),256,32;dummy9:(0,1),288,32;dummy10:(2,2),320,32;;Tcl_CallFrame:t(119,97)=(119,95)Tcl_CmdInfo:T(119,98)=s32isNativeObjectProc:(0,1),0,32;\objProc:(119,99)=*(119,69),32,32;objClientData:(119,1),64,32;\proc:(119,100)=*(119,45),96,32;clientData:(119,1),128,32;\deleteProc:(119,101)=*(119,44),160,32;deleteData:(119,1),192,32;\namespacePtr:(119,96),224,32;;Tcl_CmdInfo:t(119,102)=(119,98)Tcl_DString:T(119,103)=s212string:(2,2),0,32;length:(0,1),32,32;\spaceAvl:(0,1),64,32;staticSpace:(119,104)=ar(0,0);0;199;(0,2),96,1600;;Tcl_DString:t(119,105)=(119,103)Tcl_HashEntry:T(119,106)=s20nextPtr:(119,107)=*(119,106),0,32;\tablePtr:(119,108)=*(119,109)=xsTcl_HashTable:,32,32;bucketPtr:(119,110)=*(119,107),64,32;\clientData:(119,1),96,32;key:(119,111)=u4oneWordValue:(2,2),0,32;\words:(119,112)=ar(0,0);0;0;(0,1),0,32;string:(119,113)=ar(0,0);0;3;(0,2),0,32;;,128,32;;Tcl_HashEntry:t(119,114)=(119,106)Tcl_HashTable:T(119,109)=s52buckets:(119,115)=*(119,116)=*(119,114),0,32;\staticBuckets:(119,117)=ar(0,0);0;3;(119,116),32,128;numBuckets:(0,1),160,32;\findProc:(119,118)=*(119,119)=f(119,116),352,32;createProc:(119,120)=*(119,121)=f(119,116),384,32;;Tcl_HashTable:t(119,122)=(119,109)Tcl_HashSearch:T(119,123)=s12tablePtr:(119,124)=*(119,122),0,32;\nextIndex:(0,1),32,32;nextEntryPtr:(119,116),64,32;;Tcl_HashSearch:t(119,125)=(119,123)Tcl_Event:T(119,16)=s8proc:(119,126)=*(119,51),0,32;nextPtr:(119,127)=*(119,16),32,32;; :T(119,128)=eTCL_QUEUE_TAIL:0,TCL_QUEUE_HEAD:1,TCL_QUEUE_MARK:2,;Tcl_QueuePosition:t(119,129)=(119,128)Tcl_Time:T(119,130)=s8sec:(0,3),0,32;usec:(0,3),32,32;;Tcl_Time:t(119,131)=(119,130)Tcl_DriverBlockModeProc:t(119,132)=(119,133)=f(0,1)Tcl_DriverCloseProc:t(119,134)=(119,135)=f(0,1)Tcl_DriverInputProc:t(119,136)=(119,137)=f(0,1)Tcl_DriverOutputProc:t(119,138)=(119,137)Tcl_DriverSeekProc:t(119,139)=(119,140)=f(0,1)Tcl_DriverSetOptionProc:t(119,141)=(119,142)=f(0,1)Tcl_DriverGetOptionProc:t(119,143)=(119,144)=f(0,1)Tcl_DriverWatchProc:t(119,145)=(119,41)Tcl_DriverGetHandleProc:t(119,146)=(119,147)=f(0,1)Tcl_EolTranslation:T(119,148)=eTCL_TRANSLATE_AUTO:0,TCL_TRANSLATE_CR:1,\Tcl_EolTranslation:t(119,149)=(119,148)Tcl_ChannelType:T(119,150)=s40typeName:(2,2),0,32;blockModeProc:(119,151)=*(119,132),32,32;\closeProc:(119,152)=*(119,134),64,32;inputProc:(119,153)=*(119,136),96,32;\outputProc:(119,154)=*(119,138),128,32;seekProc:(119,155)=*(119,139),160,32;\setOptionProc:(119,156)=*(119,141),192,32;getOptionProc:(119,157)=*(119,143),224,32;\watchProc:(119,158)=*(119,145),256,32;getHandleProc:(119,159)=*(119,146),288,32;;Tcl_ChannelType:t(119,160)=(119,150)Tcl_PathType:T(119,161)=eTCL_PATH_ABSOLUTE:0,TCL_PATH_RELATIVE:1,\Tcl_PathType:t(119,162)=(119,161)XPointer:t(121,1)=(2,2)_XExtData:T(121,2)=s16number:(0,1),0,32;next:(121,3)=*(121,2),32,32;\free_private:(121,4)=*(121,5)=f(0,1),64,32;private_data:(121,1),96,32;;XExtData:t(121,6)=(121,2)XExtCodes:t(121,7)=(121,8)=s16extension:(0,1),0,32;major_opcode:(0,1),32,32;\XPixmapFormatValues:t(121,9)=(121,10)=s12depth:(0,1),0,32;\XGCValues:t(121,11)=(121,12)=s92function:(0,1),0,32;plane_mask:(0,5),32,32;\arc_mode:(0,1),320,32;tile:(122,9),352,32;stipple:(122,9),384,32;\font:(122,8),480,32;subwindow_mode:(0,1),512,32;\clip_y_origin:(0,1),608,32;clip_mask:(122,9),640,32;\GC:t(121,13)=(121,14)=*(121,15)=xs_XGC:Visual:t(121,16)=(121,17)=s32ext_data:(121,18)=*(121,6),0,32;\visualid:(122,4),32,32;class:(0,1),64,32;red_mask:(0,5),96,32;\Depth:t(121,19)=(121,20)=s12depth:(0,1),0,32;nvisuals:(0,1),32,32;\visuals:(121,21)=*(121,16),64,32;;Screen:t(121,22)=(121,23)=s80ext_data:(121,18),0,32;display:(121,24)=*(121,25)=xs_XDisplay:,32,32;\root:(122,6),64,32;width:(0,1),96,32;height:(0,1),128,32;\depths:(121,26)=*(121,19),256,32;root_depth:(0,1),288,32;\root_visual:(121,21),320,32;default_gc:(121,13),352,32;\cmap:(122,11),384,32;white_pixel:(0,5),416,32;black_pixel:(0,5),448,32;\ScreenFormat:t(121,27)=(121,28)=s16ext_data:(121,18),0,32;\XSetWindowAttributes:t(121,29)=(121,30)=s60background_pixmap:(122,9),0,32;\background_pixel:(0,5),32,32;border_pixmap:(122,9),64,32;\colormap:(122,11),416,32;cursor:(122,10),448,32;;XWindowAttributes:t(121,31)=(121,32)=s92x:(0,1),0,32;y:(0,1),32,32;\depth:(0,1),160,32;visual:(121,21),192,32;root:(122,6),224,32;\colormap:(122,11),480,32;map_installed:(0,1),512,32;\override_redirect:(0,1),672,32;screen:(121,33)=*(121,22),704,32;;XHostAddress:t(121,34)=(121,35)=s12family:(0,1),0,32;length:(0,1),32,32;\address:(2,2),64,32;;funcs:T(121,36)=s24create_image:(121,37)=*(121,38)=f(121,39)=*(121,40)=xs_XImage:,0,32;\destroy_image:(121,41)=*(121,42)=f(0,1),32,32;get_pixel:(121,43)=*(121,44)=f(0,5),64,32;\put_pixel:(121,45)=*(121,46)=f(0,1),96,32;sub_image:(121,47)=*(121,48)=f(121,39),128,32;\add_pixel:(121,49)=*(121,50)=f(0,1),160,32;;_XImage:T(121,40)=s88width:(0,1),0,32;height:(0,1),32,32;\xoffset:(0,1),64,32;format:(0,1),96,32;data:(2,2),128,32;\obdata:(121,1),480,32;f:(121,36),512,192;;XImage:t(121,51)=(121,40)XWindowChanges:t(121,52)=(121,53)=s28x:(0,1),0,32;y:(0,1),32,32;\sibling:(122,6),160,32;stack_mode:(0,1),192,32;;XColor:t(121,54)=(121,55)=s12pixel:(0,5),0,32;red:(0,9),32,16;\XSegment:t(121,56)=(121,57)=s8x1:(0,8),0,16;y1:(0,8),16,16;\XPoint:t(121,58)=(121,59)=s4x:(0,8),0,16;y:(0,8),16,16;;XRectangle:t(121,60)=(121,61)=s8x:(0,8),0,16;y:(0,8),16,16;\XArc:t(121,62)=(121,63)=s12x:(0,8),0,16;y:(0,8),16,16;\XKeyboardControl:t(121,64)=(121,65)=s32key_click_percent:(0,1),0,32;\XKeyboardState:t(121,66)=(121,67)=s56key_click_percent:(0,1),0,32;\global_auto_repeat:(0,1),160,32;auto_repeats:(121,68)=ar(0,0);0;31;(0,2),192,256;;XTimeCoord:t(121,69)=(121,70)=s8time:(122,5),0,32;x:(0,8),32,16;\XModifierKeymap:t(121,71)=(121,72)=s8max_keypermod:(0,1),0,32;\modifiermap:(121,73)=*(122,14),32,32;;Display:t(121,74)=(121,25)_XPrivDisplay:t(121,75)=(121,76)=*(121,77)=s176ext_data:(121,18),0,32;\private1:(121,78)=*(121,79)=xs_XPrivate:,32,32;fd:(0,1),64,32;\proto_minor_version:(0,1),160,32;vendor:(2,2),192,32;\private3:(122,1),224,32;private4:(122,1),256,32;private5:(122,1),288,32;\private6:(0,1),320,32;resource_alloc:(121,80)=*(121,81)=f(122,1),352,32;\nformats:(0,1),512,32;pixmap_format:(121,82)=*(121,27),544,32;\private8:(0,1),576,32;release:(0,1),608,32;private9:(121,78),640,32;\private10:(121,78),672,32;qlen:(0,1),704,32;last_request_read:(0,5),736,32;\request:(0,5),768,32;private11:(121,1),800,32;private12:(121,1),832,32;\private13:(121,1),864,32;private14:(121,1),896,32;\max_request_size:(0,4),928,32;db:(121,83)=*(121,84)=xs_XrmHashBucketRec:,960,32;\private15:(121,85)=*(121,86)=f(0,1),992,32;display_name:(2,2),1024,32;\screens:(121,33),1120,32;motion_buffer:(0,5),1152,32;\max_keycode:(0,1),1248,32;private17:(121,1),1280,32;\private18:(121,1),1312,32;private19:(0,1),1344,32;\xdefaults:(2,2),1376,32;;XKeyEvent:t(121,87)=(121,88)=s60type:(0,1),0,32;serial:(0,5),32,32;\send_event:(0,1),64,32;display:(121,89)=*(121,74),96,32;\window:(122,6),128,32;root:(122,6),160,32;subwindow:(122,6),192,32;\time:(122,5),224,32;x:(0,1),256,32;y:(0,1),288,32;\XKeyPressedEvent:t(121,90)=(121,87)XKeyReleasedEvent:t(121,91)=(121,87)XButtonEvent:t(121,92)=(121,93)=s60type:(0,1),0,32;serial:(0,5),32,32;\send_event:(0,1),64,32;display:(121,89),96,32;\XButtonPressedEvent:t(121,94)=(121,92)XButtonReleasedEvent:t(121,95)=(121,92)XMotionEvent:t(121,96)=(121,97)=s60type:(0,1),0,32;serial:(0,5),32,32;\XPointerMovedEvent:t(121,98)=(121,96)XCrossingEvent:t(121,99)=(121,100)=s68type:(0,1),0,32;serial:(0,5),32,32;\XEnterWindowEvent:t(121,101)=(121,99)XLeaveWindowEvent:t(121,102)=(121,99)XFocusChangeEvent:t(121,103)=(121,104)=s28type:(0,1),0,32;\serial:(0,5),32,32;send_event:(0,1),64,32;display:(121,89),96,32;\window:(122,6),128,32;mode:(0,1),160,32;detail:(0,1),192,32;;XFocusInEvent:t(121,105)=(121,103)XFocusOutEvent:t(121,106)=(121,103)XKeymapEvent:t(121,107)=(121,108)=s52type:(0,1),0,32;serial:(0,5),32,32;\window:(122,6),128,32;key_vector:(121,68),160,256;;XExposeEvent:t(121,109)=(121,110)=s40type:(0,1),0,32;serial:(0,5),32,32;\window:(122,6),128,32;x:(0,1),160,32;y:(0,1),192,32;\XGraphicsExposeEvent:t(121,111)=(121,112)=s48type:(0,1),0,32;\drawable:(122,7),128,32;x:(0,1),160,32;y:(0,1),192,32;\XNoExposeEvent:t(121,113)=(121,114)=s28type:(0,1),0,32;serial:(0,5),32,32;\drawable:(122,7),128,32;major_code:(0,1),160,32;\XVisibilityEvent:t(121,115)=(121,116)=s24type:(0,1),0,32;\window:(122,6),128,32;state:(0,1),160,32;;XCreateWindowEvent:t(121,117)=(121,118)=s48type:(0,1),0,32;\parent:(122,6),128,32;window:(122,6),160,32;x:(0,1),192,32;\XDestroyWindowEvent:t(121,119)=(121,120)=s24type:(0,1),0,32;\event:(122,6),128,32;window:(122,6),160,32;;XUnmapEvent:t(121,121)=(121,122)=s28type:(0,1),0,32;serial:(0,5),32,32;\event:(122,6),128,32;window:(122,6),160,32;from_configure:(0,1),192,32;;XMapEvent:t(121,123)=(121,124)=s28type:(0,1),0,32;serial:(0,5),32,32;\event:(122,6),128,32;window:(122,6),160,32;override_redirect:(0,1),192,32;;XMapRequestEvent:t(121,125)=(121,126)=s24type:(0,1),0,32;\parent:(122,6),128,32;window:(122,6),160,32;;XReparentEvent:t(121,127)=(121,128)=s40type:(0,1),0,32;serial:(0,5),32,32;\event:(122,6),128,32;window:(122,6),160,32;parent:(122,6),192,32;\XConfigureEvent:t(121,129)=(121,130)=s52type:(0,1),0,32;serial:(0,5),32,32;\event:(122,6),128,32;window:(122,6),160,32;x:(0,1),192,32;\border_width:(0,1),320,32;above:(122,6),352,32;\XGravityEvent:t(121,131)=(121,132)=s32type:(0,1),0,32;serial:(0,5),32,32;\XResizeRequestEvent:t(121,133)=(121,134)=s28type:(0,1),0,32;\window:(122,6),128,32;width:(0,1),160,32;height:(0,1),192,32;;XConfigureRequestEvent:t(121,135)=(121,136)=s56type:(0,1),0,32;\XCirculateEvent:t(121,137)=(121,138)=s28type:(0,1),0,32;serial:(0,5),32,32;\event:(122,6),128,32;window:(122,6),160,32;place:(0,1),192,32;;XCirculateRequestEvent:t(121,139)=(121,140)=s28type:(0,1),0,32;\parent:(122,6),128,32;window:(122,6),160,32;place:(0,1),192,32;;XPropertyEvent:t(121,141)=(121,142)=s32type:(0,1),0,32;serial:(0,5),32,32;\window:(122,6),128,32;atom:(122,3),160,32;time:(122,5),192,32;\XSelectionClearEvent:t(121,143)=(121,144)=s28type:(0,1),0,32;\window:(122,6),128,32;selection:(122,3),160,32;time:(122,5),192,32;;XSelectionRequestEvent:t(121,145)=(121,146)=s40type:(0,1),0,32;\owner:(122,6),128,32;requestor:(122,6),160,32;selection:(122,3),192,32;\target:(122,3),224,32;property:(122,3),256,32;time:(122,5),288,32;;XSelectionEvent:t(121,147)=(121,148)=s36type:(0,1),0,32;serial:(0,5),32,32;\requestor:(122,6),128,32;selection:(122,3),160,32;\target:(122,3),192,32;property:(122,3),224,32;time:(122,5),256,32;;XColormapEvent:t(121,149)=(121,150)=s32type:(0,1),0,32;serial:(0,5),32,32;\window:(122,6),128,32;colormap:(122,11),160,32;new:(0,1),192,32;\XClientMessageEvent:t(121,151)=(121,152)=s48type:(0,1),0,32;\window:(122,6),128,32;message_type:(122,3),160,32;\format:(0,1),192,32;data:(121,153)=u20b:(121,154)=ar(0,0);0;19;(0,2),0,160;\s:(121,155)=ar(0,0);0;9;(0,8),0,160;l:(121,156)=ar(0,0);0;4;(0,3),0,160;;,224,160;;XMappingEvent:t(121,157)=(121,158)=s32type:(0,1),0,32;serial:(0,5),32,32;\window:(122,6),128,32;request:(0,1),160,32;first_keycode:(0,1),192,32;\XErrorEvent:t(121,159)=(121,160)=s20type:(0,1),0,32;display:(121,89),32,32;\resourceid:(122,1),64,32;serial:(0,5),96,32;error_code:(0,11),128,8;\XAnyEvent:t(121,161)=(121,162)=s20type:(0,1),0,32;serial:(0,5),32,32;\window:(122,6),128,32;;_XEvent:T(121,163)=u96type:(0,1),0,32;xany:(121,161),0,160;\xkey:(121,87),0,480;xbutton:(121,92),0,480;xmotion:(121,96),0,480;\xcrossing:(121,99),0,544;xfocus:(121,103),0,224;xexpose:(121,109),0,320;\xgraphicsexpose:(121,111),0,384;xnoexpose:(121,113),0,224;\xvisibility:(121,115),0,192;xcreatewindow:(121,117),0,384;\xdestroywindow:(121,119),0,192;xunmap:(121,121),0,224;\xmap:(121,123),0,224;xmaprequest:(121,125),0,192;xreparent:(121,127),0,320;\xconfigure:(121,129),0,416;xgravity:(121,131),0,256;\xresizerequest:(121,133),0,224;xconfigurerequest:(121,135),0,448;\xcirculate:(121,137),0,224;xcirculaterequest:(121,139),0,224;\xproperty:(121,141),0,256;xselectionclear:(121,143),0,224;\xselectionrequest:(121,145),0,320;xselection:(121,147),0,288;\xcolormap:(121,149),0,256;xclient:(121,151),0,384;xmapping:(121,157),0,256;\xerror:(121,159),0,160;xkeymap:(121,107),0,416;pad:(121,164)=ar(0,0);0;23;(0,3),0,768;;XEvent:t(121,165)=(121,163)XCharStruct:t(121,166)=(121,167)=s12lbearing:(0,8),0,16;rbearing:(0,8),16,16;\XFontProp:t(121,168)=(121,169)=s8name:(122,3),0,32;card32:(0,5),32,32;;XFontStruct:t(121,170)=(121,171)=s80ext_data:(121,18),0,32;fid:(122,8),32,32;\properties:(121,172)=*(121,168),320,32;min_bounds:(121,166),352,96;\max_bounds:(121,166),448,96;per_char:(121,173)=*(121,166),544,32;\XTextItem:t(121,174)=(121,175)=s16chars:(2,2),0,32;nchars:(0,1),32,32;\delta:(0,1),64,32;font:(122,8),96,32;;XChar2b:t(121,176)=(121,177)=s4byte1:(0,11),0,8;byte2:(0,11),8,8;;XTextItem16:t(121,178)=(121,179)=s16chars:(121,180)=*(121,176),0,32;\nchars:(0,1),32,32;delta:(0,1),64,32;font:(122,8),96,32;;XEDataObject:t(121,181)=(121,182)=u4display:(121,89),0,32;gc:(121,13),0,32;\visual:(121,21),0,32;screen:(121,33),0,32;pixmap_format:(121,82),0,32;\font:(121,183)=*(121,170),0,32;;XFontSetExtents:t(121,184)=(121,185)=s16max_ink_extent:(121,60),0,64;\max_logical_extent:(121,60),64,64;;XOM:t(121,186)=(121,187)=*(121,188)=xs_XOM:XOC:t(121,189)=(121,190)=*(121,191)=xs_XOC:XFontSet:t(121,192)=(121,190)XmbTextItem:t(121,193)=(121,194)=s16chars:(2,2),0,32;nchars:(0,1),32,32;\delta:(0,1),64,32;font_set:(121,192),96,32;;XwcTextItem:t(121,195)=(121,196)=s16chars:(121,197)=*(47,1),0,32;\nchars:(0,1),32,32;delta:(0,1),64,32;font_set:(121,192),96,32;;XOMCharSetList:t(121,198)=(121,199)=s8charset_count:(0,1),0,32;\charset_list:(89,2),32,32;; :T(121,200)=eXOMOrientation_LTR_TTB:0,XOMOrientation_RTL_TTB:1,\XOrientation:t(121,201)=(121,200)XOMOrientation:t(121,202)=(121,203)=s8num_orientation:(0,1),0,32;\orientation:(121,204)=*(121,201),32,32;;XOMFontInfo:t(121,205)=(121,206)=s12num_font:(0,1),0,32;font_struct_list:(121,207)=*(121,183),32,32;\font_name_list:(89,2),64,32;;XIM:t(121,208)=(121,209)=*(121,210)=xs_XIM:XIC:t(121,211)=(121,212)=*(121,213)=xs_XIC:XIMProc:t(121,214)=(121,215)=*(121,216)=f(0,19)XICProc:t(121,217)=(121,218)=*(121,219)=f(0,1)XIDProc:t(121,220)=(121,221)=*(121,222)=f(0,19)XIMStyle:t(121,223)=(0,5)XIMStyles:t(121,224)=(121,225)=s8count_styles:(0,9),0,16;\supported_styles:(121,226)=*(121,223),32,32;;XVaNestedList:t(121,227)=(13,2)XIMCallback:t(121,228)=(121,229)=s8client_data:(121,1),0,32;\callback:(121,214),32,32;;XICCallback:t(121,230)=(121,231)=s8client_data:(121,1),0,32;\callback:(121,217),32,32;;XIMFeedback:t(121,232)=(0,5)_XIMText:T(121,233)=s16length:(0,9),0,16;feedback:(121,234)=*(121,232),32,32;\encoding_is_wchar:(0,1),64,32;string:(121,235)=u4multi_byte:(2,2),0,32;\wide_char:(121,197),0,32;;,96,32;;XIMText:t(121,236)=(121,233)XIMPreeditState:t(121,237)=(0,5)_XIMPreeditStateNotifyCallbackStruct:T(121,238)=s4state:(121,237),0,32;;XIMPreeditStateNotifyCallbackStruct:t(121,239)=(121,238)XIMResetState:t(121,240)=(0,5)XIMStringConversionFeedback:t(121,241)=(0,5)_XIMStringConversionText:T(121,242)=s16length:(0,9),0,16;\feedback:(121,243)=*(121,241),32,32;encoding_is_wchar:(0,1),64,32;\string:(121,244)=u4mbs:(2,2),0,32;wcs:(121,197),0,32;;,96,32;;XIMStringConversionText:t(121,245)=(121,242)XIMStringConversionPosition:t(121,246)=(0,9)XIMStringConversionType:t(121,247)=(0,9)XIMStringConversionOperation:t(121,248)=(0,9) :T(121,249)=eXIMForwardChar:0,XIMBackwardChar:1,XIMForwardWord:2,\XIMCaretDirection:t(121,250)=(121,249)_XIMStringConversionCallbackStruct:T(121,251)=s16position:(121,246),0,16;\direction:(121,250),32,32;operation:(121,248),64,16;\factor:(0,9),80,16;text:(121,252)=*(121,245),96,32;;XIMStringConversionCallbackStruct:t(121,253)=(121,251)_XIMPreeditDrawCallbackStruct:T(121,254)=s16caret:(0,1),0,32;\text:(121,255)=*(121,236),96,32;;XIMPreeditDrawCallbackStruct:t(121,256)=(121,254) :T(121,257)=eXIMIsInvisible:0,XIMIsPrimary:1,XIMIsSecondary:2,;XIMCaretStyle:t(121,258)=(121,257)_XIMPreeditCaretCallbackStruct:T(121,259)=s12position:(0,1),0,32;\direction:(121,250),32,32;style:(121,258),64,32;;XIMPreeditCaretCallbackStruct:t(121,260)=(121,259) :T(121,261)=eXIMTextType:0,XIMBitmapType:1,;XIMStatusDataType:t(121,262)=(121,261)_XIMStatusDrawCallbackStruct:T(121,263)=s8type:(121,262),0,32;\data:(121,264)=u4text:(121,255),0,32;bitmap:(122,9),0,32;;,32,32;;XIMStatusDrawCallbackStruct:t(121,265)=(121,263)_XIMHotKeyTrigger:T(121,266)=s12keysym:(122,13),0,32;modifier:(0,1),32,32;\XIMHotKeyTrigger:t(121,267)=(121,266)_XIMHotKeyTriggers:T(121,268)=s8num_hot_key:(0,1),0,32;\key:(121,269)=*(121,267),32,32;;XIMHotKeyTriggers:t(121,270)=(121,268)XIMHotKeyState:t(121,271)=(0,5)XIMValuesList:t(121,272)=(121,273)=s8count_values:(0,9),0,16;\supported_values:(89,2),32,32;;XErrorHandler:t(121,274)=(121,275)=*(121,276)=f(0,1)XIOErrorHandler:t(121,277)=(121,278)=*(121,279)=f(0,1)XConnectionWatchProc:t(121,280)=(121,281)=*(121,282)=f(0,19)Tk_BindingTable:t(120,1)=(120,2)=*(120,3)=xsTk_BindingTable_:Tk_Canvas:t(120,4)=(120,5)=*(120,6)=xsTk_Canvas_:Tk_Cursor:t(120,7)=(120,8)=*(120,9)=xsTk_Cursor_:Tk_ErrorHandler:t(120,10)=(120,11)=*(120,12)=xsTk_ErrorHandler_:Tk_Font:t(120,13)=(120,14)=*(120,15)=xsTk_Font_:Tk_Image:t(120,16)=(120,17)=*(120,18)=xsTk_Image__:Tk_ImageMaster:t(120,19)=(120,20)=*(120,21)=xsTk_ImageMaster_:Tk_TextLayout:t(120,22)=(120,23)=*(120,24)=xsTk_TextLayout_:Tk_Window:t(120,25)=(120,26)=*(120,27)=xsTk_Window_:Tk_3DBorder:t(120,28)=(120,29)=*(120,30)=xsTk_3DBorder_:Tk_Uid:t(120,31)=(2,2)Tk_ArgvInfo:t(120,32)=(120,33)=s20key:(2,2),0,32;type:(0,1),32,32;\src:(2,2),64,32;dst:(2,2),96,32;help:(2,2),128,32;;Tk_OptionParseProc:t(120,34)=(120,35)=f(0,1)Tk_OptionPrintProc:t(120,36)=(120,37)=f(2,2)Tk_CustomOption:T(120,38)=s12parseProc:(120,39)=*(120,34),0,32;\printProc:(120,40)=*(120,36),32,32;clientData:(119,1),64,32;;Tk_CustomOption:t(120,41)=(120,38)Tk_ConfigSpec:T(120,42)=s32type:(0,1),0,32;argvName:(2,2),32,32;\dbName:(2,2),64,32;dbClass:(2,2),96,32;defValue:(2,2),128,32;\offset:(0,1),160,32;specFlags:(0,1),192,32;customPtr:(120,43)=*(120,41),224,32;;Tk_ConfigSpec:t(120,44)=(120,42) :T(120,45)=eTK_DEFER_EVENT:0,TK_PROCESS_EVENT:1,\Tk_RestrictAction:t(120,46)=(120,45) :T(120,47)=eTK_ANCHOR_N:0,TK_ANCHOR_NE:1,TK_ANCHOR_E:2,\Tk_Anchor:t(120,48)=(120,47) :T(120,49)=eTK_JUSTIFY_LEFT:0,TK_JUSTIFY_RIGHT:1,\Tk_Justify:t(120,50)=(120,49)Tk_FontMetrics:T(120,51)=s12ascent:(0,1),0,32;descent:(0,1),32,32;\Tk_FontMetrics:t(120,52)=(120,51)Tk_GeomRequestProc:t(120,53)=(120,54)=f(0,19)Tk_GeomLostSlaveProc:t(120,55)=(120,54)Tk_GeomMgr:T(120,56)=s12name:(2,2),0,32;requestProc:(120,57)=*(120,53),32,32;\lostSlaveProc:(120,58)=*(120,55),64,32;;Tk_GeomMgr:t(120,59)=(120,56)XVirtualEvent:t(120,60)=(120,61)=s60type:(0,1),0,32;serial:(0,5),32,32;\event:(122,6),128,32;root:(122,6),160,32;subwindow:(122,6),192,32;\name:(120,31),416,32;same_screen:(0,1),448,32;;XActivateDeactivateEvent:t(120,62)=(120,63)=s20type:(0,1),0,32;\XActivateEvent:t(120,64)=(120,62)XDeactivateEvent:t(120,65)=(120,62)Tk_FakeWin:T(120,66)=s216display:(121,89),0,32;dummy1:(2,2),32,32;\screenNum:(0,1),64,32;visual:(121,21),96,32;depth:(0,1),128,32;\window:(122,6),160,32;dummy2:(2,2),192,32;dummy3:(2,2),224,32;\parentPtr:(120,25),256,32;dummy4:(2,2),288,32;dummy5:(2,2),320,32;\pathName:(2,2),352,32;nameUid:(120,31),384,32;classUid:(120,31),416,32;\changes:(121,52),448,224;dummy6:(0,4),672,32;atts:(121,29),704,480;\dummy7:(0,5),1184,32;flags:(0,4),1216,32;dummy8:(2,2),1248,32;\dummy9:(121,211),1280,32;dummy10:(120,67)=*(119,1),1312,32;\dummy11:(0,1),1344,32;dummy12:(0,1),1376,32;dummy13:(2,2),1408,32;\dummy14:(2,2),1440,32;dummy15:(119,1),1472,32;reqWidth:(0,1),1504,32;\dummy16:(2,2),1600,32;dummy17:(2,2),1632,32;dummy18:(119,1),1664,32;\dummy19:(2,2),1696,32;;Tk_FakeWin:t(120,68)=(120,66)Tk_Item:T(120,69)=s52id:(0,1),0,32;nextPtr:(120,70)=*(120,69),32,32;\staticTagSpace:(120,71)=ar(0,0);0;2;(120,31),64,96;tagPtr:(120,72)=*(120,31),160,32;\tagSpace:(0,1),192,32;numTags:(0,1),224,32;typePtr:(120,73)=*(120,74)=xsTk_ItemType:,256,32;\Tk_Item:t(120,75)=(120,69)Tk_ItemCreateProc:t(120,76)=(120,77)=f(0,1)Tk_ItemConfigureProc:t(120,78)=(120,79)=f(0,1)Tk_ItemCoordProc:t(120,80)=(120,77)Tk_ItemDeleteProc:t(120,81)=(120,82)=f(0,19)Tk_ItemDisplayProc:t(120,83)=(120,84)=f(0,19)Tk_ItemPointProc:t(120,85)=(120,86)=f(0,13)Tk_ItemAreaProc:t(120,87)=(120,88)=f(0,1)Tk_ItemPostscriptProc:t(120,89)=(120,90)=f(0,1)Tk_ItemScaleProc:t(120,91)=(120,92)=f(0,19)Tk_ItemTranslateProc:t(120,93)=(120,94)=f(0,19)Tk_ItemIndexProc:t(120,95)=(120,96)=f(0,1)Tk_ItemCursorProc:t(120,97)=(120,98)=f(0,19)Tk_ItemSelectionProc:t(120,99)=(120,100)=f(0,1)Tk_ItemInsertProc:t(120,101)=(120,102)=f(0,19)Tk_ItemDCharsProc:t(120,103)=(120,104)=f(0,19)Tk_ItemType:T(120,74)=s80name:(2,2),0,32;itemSize:(0,1),32,32;\createProc:(120,105)=*(120,76),64,32;configSpecs:(120,106)=*(120,44),96,32;\configProc:(120,107)=*(120,78),128,32;coordProc:(120,108)=*(120,80),160,32;\deleteProc:(120,109)=*(120,81),192,32;displayProc:(120,110)=*(120,83),224,32;\alwaysRedraw:(0,1),256,32;pointProc:(120,111)=*(120,85),288,32;\areaProc:(120,112)=*(120,87),320,32;postscriptProc:(120,113)=*(120,89),352,32;\scaleProc:(120,114)=*(120,91),384,32;translateProc:(120,115)=*(120,93),416,32;\indexProc:(120,116)=*(120,95),448,32;icursorProc:(120,117)=*(120,97),480,32;\selectionProc:(120,118)=*(120,99),512,32;insertProc:(120,119)=*(120,101),544,32;\dCharsProc:(120,120)=*(120,103),576,32;nextPtr:(120,73),608,32;;Tk_ItemType:t(120,121)=(120,74)Tk_CanvasTextInfo:T(120,122)=s56selBorder:(120,28),0,32;selBorderWidth:(0,1),32,32;\selFgColorPtr:(120,123)=*(121,54),64,32;selItemPtr:(120,124)=*(120,75),96,32;\anchorItemPtr:(120,124),192,32;selectAnchor:(0,1),224,32;\insertBorder:(120,28),256,32;insertWidth:(0,1),288,32;\insertBorderWidth:(0,1),320,32;focusItemPtr:(120,124),352,32;\Tk_CanvasTextInfo:t(120,125)=(120,122)Tk_ImageType:t(120,126)=(120,127)=xsTk_ImageType:Tk_ImageCreateProc:t(120,128)=(120,129)=f(0,1)Tk_ImageGetProc:t(120,130)=(120,131)=f(119,1)Tk_ImageDisplayProc:t(120,132)=(120,133)=f(0,19)Tk_ImageFreeProc:t(120,134)=(120,135)=f(0,19)Tk_ImageDeleteProc:t(120,136)=(119,43)Tk_ImageChangedProc:t(120,137)=(120,138)=f(0,19)Tk_ImageType:T(120,127)=s28name:(2,2),0,32;createProc:(120,139)=*(120,128),32,32;\getProc:(120,140)=*(120,130),64,32;displayProc:(120,141)=*(120,132),96,32;\freeProc:(120,142)=*(120,134),128,32;deleteProc:(120,143)=*(120,136),160,32;\nextPtr:(120,144)=*(120,127),192,32;;Tk_PhotoHandle:t(120,145)=(13,2)Tk_PhotoImageBlock:T(120,146)=s32pixelPtr:(120,147)=*(0,11),0,32;\pixelSize:(0,1),128,32;offset:(120,148)=ar(0,0);0;2;(0,1),160,96;;Tk_PhotoImageBlock:t(120,149)=(120,146)Tk_PhotoImageFormat:t(120,150)=(120,151)=xsTk_PhotoImageFormat:Tk_ImageFileMatchProc:t(120,152)=(120,153)=f(0,1)Tk_ImageStringMatchProc:t(120,154)=(120,155)=f(0,1)Tk_ImageFileReadProc:t(120,156)=(120,157)=f(0,1)Tk_ImageStringReadProc:t(120,158)=(120,159)=f(0,1)Tk_ImageFileWriteProc:t(120,160)=(120,161)=f(0,1)Tk_ImageStringWriteProc:t(120,162)=(120,163)=f(0,1)Tk_PhotoImageFormat:T(120,151)=s32name:(2,2),0,32;fileMatchProc:(120,164)=*(120,152),32,32;\stringMatchProc:(120,165)=*(120,154),64,32;fileReadProc:(120,166)=*(120,156),96,32;\stringReadProc:(120,167)=*(120,158),128,32;fileWriteProc:(120,168)=*(120,160),160,32;\stringWriteProc:(120,169)=*(120,162),192,32;nextPtr:(120,170)=*(120,151),224,32;;Tk_ErrorProc:t(120,171)=(120,172)=f(0,1)Tk_EventProc:t(120,173)=(120,174)=f(0,19)Tk_GenericProc:t(120,175)=(120,176)=f(0,1)Tk_GetSelProc:t(120,177)=(120,178)=f(0,1)Tk_LostSelProc:t(120,179)=(119,43)Tk_RestrictProc:t(120,180)=(120,181)=f(120,46)Tk_SelectionProc:t(120,182)=(120,183)=f(0,1)advert_data:T(41,1)=s60interval:(0,4),0,32;end_time:(0,5),32,32;\aid:(2,2),64,32;data:(2,2),96,32;tx_sock:(0,1),128,32;\authinfo:(41,2)=*(41,3)=xsauth_info:,160,32;sap_hdr:(41,4)=*(41,5)=xssap_header:,192,32;\sapenc_p:(41,6)=*(41,7)=xspriv_header:,224,32;ttl:(0,11),256,8;\next_ad:(41,8)=*(41,1),384,32;prev_ad:(41,8),416,32;\timer_token:(119,23),448,32;;sap_header:T(41,5)=s8compress:(28,3),0,1;enc:(28,3),1,1;\type:(28,3),2,3;version:(28,3),5,3;authlen:(28,3),8,8;\msgid:(28,3),16,16;src:(28,3),32,32;;auth_info:T(41,3)=s40auth_type:(28,3),0,32;padding:(28,3),32,32;\version:(28,3),64,32;siglen:(28,3),96,32;autlen:(28,3),128,32;\pad_len:(28,3),160,32;sig_len:(28,3),192,32;key_len:(28,3),224,32;\signature:(2,2),256,32;keycertificate:(2,2),288,32;;auth_header:T(41,9)=s4auth_type:(28,3),0,4;padding:(28,3),4,1;\version:(28,3),5,3;siglen:(28,3),8,8;;priv_header:T(41,7)=s24enc_type:(28,3),0,4;padding:(28,3),4,1;\version:(28,3),5,3;hdr_len:(28,3),8,8;pad_len:(28,3),32,32;\txt_len:(28,3),64,32;encd_len:(28,3),96,32;enc_data:(2,2),128,32;\txt_data:(2,2),160,32;;enc_header:T(41,10)=s4timeout:(28,3),0,32;;hash_t:t(41,11)=(0,4)lsdap_header:T(41,12)=s4check:(28,1),0,8;type:(28,1),8,8;\payload:(45,5),16,8;;lsdap_advert:T(41,13)=s12check:(28,1),0,8;type:(28,1),8,8;\origin:(28,1),16,8;ttl:(28,1),24,8;hash:(41,11),32,32;\addata:(45,5),64,8;;lsdap_hashlist:T(41,14)=s8check:(28,1),0,8;type:(28,1),8,8;\seq:(28,1),16,8;padding2:(28,1),24,8;hashlist:(41,15)=ar(0,0);0;0;(41,11),32,32;;lsdap_hashreq:T(41,16)=s8check:(28,1),0,8;type:(28,1),8,8;\padding1:(28,1),16,8;padding2:(28,1),24,8;hash:(41,11),32,32;;../src/sip.hconnection_s:T(133,1)=s36fd:(0,1),0,32;used:(0,1),32,32;\buf:(2,2),64,32;bufsize:(0,1),96,32;len:(0,1),128,32;\addr:(2,2),160,32;host:(2,2),192,32;callid:(2,2),224,32;\port:(0,1),256,32;;connection:t(133,2)=(133,1)../src/prototypes_crypt.hfirst_ad:S(41,8)last_ad:S(41,8)no_of_ads:S(0,1)seedrand:F(0,19)tv:(97,1)remove_cr:F(0,19)str:P(2,2)hexdump:F(0,19)buf:P(2,2)i:r(0,1)val:r(0,1)p:r(2,2)no_of_rx_socks:G(0,1)no_of_tx_socks:G(0,1)ttl:G(0,11)doexit:G(0,1)ui_visible:G(0,1)debug1:G(0,1)dump:F(0,19)buflen:P(0,1)sd_listen:F(0,1)address:P(2,2)port:P(0,1)rx_sock:P(0,20)=*(0,1)no_of_socks:P(0,20)fatal:p(0,1)fatal:r(0,1)name:(67,10)imr:(70,3)group:r(0,4)s:r(0,1)one:(0,1)zero:(0,1)sd_tx:F(0,1)txsock:P(0,20)load_cache_entry:F(0,1)dummy:P(119,1)interp:p(0,21)=*(119,5)acgc:P(0,1)argv:p(89,2)buf:(0,22)=ar(0,0);0;2047;(0,2)p:(2,2)advert:(0,23)=ar(0,0);0;2047;(0,2)new_data:(0,24)=ar(0,0);0;2047;(0,2)sap_addr:(121,154)aid:(0,25)=ar(0,0);0;79;(0,2)k1:r(2,2)k2:r(2,2)encbuf:r(2,2)newbuf:(0,26)=ar(0,0);0;2047;(0,2)newlength:(0,1)sap_port:(0,1)len:(0,1)ttl:(0,1)hdr_len:(0,1)auth_len:r(0,1)data_len:(0,1)new_len:r(0,1)enc_data_len:(0,1)irand:(0,1)enc_enc:(0,1)origsrc:(0,5)src:(0,5)endtime:(0,5)t:(29,1)enc_fd:r(0,27)=*(42,1)sbuf:(37,1)bp:r(41,4)debugbuf:V(0,28)=ar(0,0);0;2047;(0,2)auth_hdr:r(0,29)=*(41,9)enc_p:(41,6)addata:(41,8)data:r(2,2)tmp_keyid:(65,3)key:(117,4)keyname:(117,4)asym_keyid:(0,30)=ar(0,0);0;8;(0,2)enc_asym_keyid:(0,31)=ar(0,0);0;8;(0,2)authtype:(0,32)=ar(0,0);0;5;(0,2)enctype:(0,33)=ar(0,0);0;5;(0,2)authstatus:(56,4)encstatus:(56,4)encstatus_p:r(2,2)authmessage:(0,34)=ar(0,0);0;399;(0,2)encmessage:(0,35)=ar(0,0);0;399;(0,2)trust:(121,154)nrandstr:(0,36)=ar(0,0);0;9;(0,2)main:F(0,1)argc:p(0,1)argv:P(89,2)inChannel:r(0,1)hstent:r(0,37)=*(88,1)a:r(89,2)dnsconf:(0,27)testhstent:r(0,37)dnsbuf:(117,4)testbuf:(117,4)cp:r(2,2)x:r(0,5)pswd:r(0,38)=*(92,1)xremove_interface:F(0,1)pdisp:P(121,89)done:V(0,1)remove_interface:F(0,19)rebuild_interface:F(0,19)recv_packets:F(0,19)fd:P(119,1)length:(0,1)orglength:(0,1)from:(67,10)hfrom:(0,5)data:(2,2)auth_hdr:r(0,29)advert:(41,8)addata:r(41,8)auth_len:(0,1)found:(0,1)has_security:(0,1)endtime:r(0,5)enc_p:r(41,6)has_encryption:(0,1)new_data:(0,39)=ar(0,0);0;2047;(0,2)aid:(121,154)asym_keyid:(0,40)=ar(0,0);0;8;(0,2)authtype:(0,41)=ar(0,0);0;5;(0,2)authmessage:(0,42)=ar(0,0);0;399;(0,2)encmessage:(0,43)=ar(0,0);0;399;(0,2)enc_asym_keyid:(0,44)=ar(0,0);0;8;(0,2)enctype:(0,45)=ar(0,0);0;5;(0,2)recvkey:(117,4)nrandstr:(0,46)=ar(0,0);0;9;(0,2)buf:(0,47)=ar(0,0);0;2047;(0,2)debugbuf:(0,48)=ar(0,0);0;2047;(0,2)ix:(0,1)set_time:f(0,19)var:P(95,3)t:P(29,1)buf:(117,4)parse_entry:F(0,5)advertid:p(2,2)data:p(2,2)length:p(0,1)src:p(0,5)hfrom:p(0,5)sap_addr:p(2,2)sap_port:p(0,1)t:p(29,1)trust:p(2,2)recvkey:p(2,2)authtype:p(2,2)authstatus:p(2,2)data_len:p(0,20)asym_keyid:p(2,2)enctype:p(2,2)encstatus:p(2,2)enc_data_len:p(0,20)enc_asym_keyid:p(2,2)authmessage:p(2,2)encmessage:p(2,2)i:(0,1)namestr:V(0,49)=ar(0,0);0;2047;(0,2)cur:(2,2)end:r(2,2)attr:(2,2)unknown:r(2,2)version:(2,2)session:(2,2)desc:(2,2)orig:(2,2)chan:(0,50)=ar(0,0);0;9;(2,2)media:(0,51)=ar(0,0);0;9;(2,2)times:(0,52)=ar(0,0);0;9;(2,2)rpt:(0,53)=ar(0,0);0;9;(0,54)=ar(0,0);0;9;(2,2)uri:(2,2)phone:(0,55)=ar(0,0);0;9;(2,2)email:(0,56)=ar(0,0);0;9;(2,2)bw:(0,57)=ar(0,0);0;9;(2,2)key:(0,58)=ar(0,0);0;9;(2,2)data2:(2,2)mediactr:(0,1)tctr:(0,1)pctr:(0,1)ectr:(0,1)bctr:(0,1)kctr:(0,1)uctr:(0,1)vars:(0,59)=ar(0,0);0;9;(0,60)=ar(0,0);0;1023;(0,2)tag:r(2,2)mediakey:(0,61)=ar(0,0);0;9;(2,2)fullkey:r(2,2)tmpstr:(0,60)fmt:(0,60)proto:(0,60)heardfrom:(0,60)origsrc:(0,60)creator:(0,60)modtime:(0,60)createtime:(0,60)createaddr:(0,60)in:(0,60)ip:(0,60)mediattl:r(0,1)medialayers:r(0,1)port:(0,1)origlen:(0,1)time1:(0,62)=ar(0,0);0;9;(0,4)time2:(0,63)=ar(0,0);0;9;(0,4)rctr:(0,64)=ar(0,0);0;9;(0,4)timemax:(0,4)maddr:(67,3)var:(121,154)r:r(0,4)extract_ttl:F(0,1)addrstr:P(2,2)ttlstr:r(2,2)extract_layers:F(0,1)layersstr:r(2,2)check_net_type:F(0,1)in:P(2,2)ip:P(2,2)timed_send_advert:F(0,1)cd:P(119,1)interval:r(0,4)authinfo:r(41,2)auth_len:r(28,3)sapenc_p:r(41,6)hdr_len:r(28,3)send_advert:F(0,1)adstr:p(2,2)tx_sock:p(0,1)ttl:p(0,11)encrypt:p(0,1)len:p(28,3)auth_len:p(28,3)authinfo:p(41,2)hdr_len:p(28,3)sapenc_p:p(41,6)sap_hdr:p(0,65)=*(41,4)buf:r(2,2)ap:r(2,2)queue_ad_for_sending:F(0,1)aid:p(2,2)interval:p(0,1)end_time:p(0,3)txaddress:p(2,2)txport:p(0,1)ttl:p(0,1)keyname:p(2,2)auth_type:p(2,2)auth_status:p(2,2)enc_type:p(2,2)enc_status:p(2,2)addata:p(41,8)no_of_ads:V(0,1)stop_session_ad:F(0,1)aid:P(2,2)clean_up_and_die:F(0,19)force_numeric:F(0,19)i:r(0,4)splat_tcl_special_chars:F(0,19)warn_tcl_special_chars:F(0,19)get_authentication_info:F(41,2)advertid:P(2,2)write_authentication:F(0,1)afilename:P(2,2)data:P(2,2)file:r(0,27)filename:(2,2)tmpfilename:(117,4)buf:(0,66)=ar(0,0);0;2047;(0,2)auth_hdr:(41,9)sap_hdr:r(41,4)get_advert_info:F(41,8)write_encryption:F(0,1)auth_type:P(2,2)hdr_len:r(0,1)sapenc_p:(41,6)run_program:F(0,1)args:P(2,2)pid:r(28,16)ptr1:r(2,2)ptr2:r(2,2)nargv:(0,67)=ar(0,0);0;39;(2,2)gui:G(0,1)cli:G(0,1)logging:G(0,1)rxsock:G(0,68)=ar(0,0);0;19;(0,1)rx_sock_addr:G(0,69)=ar(0,0);0;19;(2,2)rx_sock_port:G(0,68)txsock:G(0,68)tx_sock_addr:G(0,69)sip_udp_rx_sock:G(0,1)sip_tcp_rx_sock:G(0,1)sip_udp_tx_sock:G(0,1)busrxsock:G(0,1)hostaddr:G(0,5)hostname:G(0,60)username:G(0,60)sipalias:G(0,25)rfd2sock:G(0,70)=ar(0,0);0;63;(0,11)env:G(38,2)../src/sdr_help.cno_of_help:G(0,1)help:G(0,20)=ar(0,0);0;22;(0,21)=*(0,2)mbone_faq.ehtmlmbone_faq:G(1,1)=ar(0,0);0;29502;(0,2)mbone_tools.ehtmlmbone_tools:G(2,1)=ar(0,0);0;8197;(0,2)bugs.ehtmlbugs:G(3,1)=ar(0,0);0;6603;(0,2)changes.ehtmlchanges:G(4,1)=ar(0,0);0;38789;(0,2)intro.ehtmlintro:G(5,1)=ar(0,0);0;1963;(0,2)node1.ehtmlnode1:G(6,1)=ar(0,0);0;2757;(0,2)node2.ehtmlnode2:G(7,1)=ar(0,0);0;1743;(0,2)node3.ehtmlnode3:G(8,1)=ar(0,0);0;746;(0,2)node4.ehtmlnode4:G(9,1)=ar(0,0);0;1171;(0,2)node5.ehtmlnode5:G(10,1)=ar(0,0);0;1944;(0,2)node6.ehtmlnode6:G(11,1)=ar(0,0);0;848;(0,2)node7.ehtmlnode7:G(12,1)=ar(0,0);0;468;(0,2)node8.ehtmlnode8:G(13,1)=ar(0,0);0;1311;(0,2)node9.ehtmlnode9:G(14,1)=ar(0,0);0;1074;(0,2)node10.ehtmlnode10:G(15,1)=ar(0,0);0;1680;(0,2)node11.ehtmlnode11:G(16,1)=ar(0,0);0;4245;(0,2)node12.ehtmlnode12:G(17,1)=ar(0,0);0;2022;(0,2)node13.ehtmlnode13:G(18,1)=ar(0,0);0;753;(0,2)node14.ehtmlnode14:G(19,1)=ar(0,0);0;1155;(0,2)node15.ehtmlnode15:G(20,1)=ar(0,0);0;429;(0,2)plugins.ehtmlplugins:G(21,1)=ar(0,0);0;1772;(0,2)plugtut.ehtmlplugtut:G(22,1)=ar(0,0);0;6351;(0,2)helpdata:G(0,20)../src/sip.cconnection_s:T(115,1)=s36fd:(0,1),0,32;used:(0,1),32,32;\buf:(9,35),64,32;bufsize:(0,1),96,32;len:(0,1),128,32;\addr:(9,35),160,32;host:(9,35),192,32;callid:(9,35),224,32;\connection:t(115,2)=(115,1)../src/dns.hdnshdr:T(116,1)=s12id:(0,4),0,16;qr:(0,4),16,1;\opcode:(0,4),17,4;aa:(0,4),21,1;tc:(0,4),22,1;\rd:(0,4),23,1;ra:(0,4),24,1;z:(0,4),25,3;\rcode:(0,4),28,4;qdcount:(0,4),32,16;ancount:(0,4),48,16;\nscount:(0,4),64,16;arcount:(0,4),80,16;;sip_recv_udp:F(0,1)pktsrc:(92,4)sip_parse_recvd_data:F(0,1)length:P(0,1)sipfd:P(0,1)srcaddr:P(9,35)sipfdstr:(0,21)=ar(0,0);0;9;(0,2)dstname:r(9,35)srcuser:(9,35)dstuser:r(9,35)path:r(9,35)cseq:r(9,35)callid:r(9,35)method:r(0,1)u_at_h:(0,22)=ar(0,0);0;79;(0,2)u_at_a:(0,23)=ar(0,0);0;79;(0,2)sip_recv_tcp:F(0,1)sip_readfrom_tcp:F(0,1)bytes:r(0,1)consumed:r(0,1)callid:(0,24)=ar(0,0);0;79;(0,2)parsebuf:r(9,35)readfds:(22,2)parse_sip_success:F(0,1)addr:P(9,35)sipfdstr:(0,25)=ar(0,0);0;9;(0,2)parse_sip_fail:F(0,1)sipfdstr:(0,26)=ar(0,0);0;9;(0,2)parse_sip_redirect:F(0,1)sipfdstr:(0,27)=ar(0,0);0;9;(0,2)parse_sip_fa:F(0,1)parse_sip_progress:F(0,1)sipfdstr:(0,28)=ar(0,0);0;9;(0,2)sdr_update_ui:F(0,19)sip_close_tcp_connection:F(0,1)callid:P(9,35)sip_tcp_conns:G(0,29)=ar(0,0);0;99;(115,2)../src/sip_common.c../src/iovec.hptrdiff_t:t(4,1)=(0,1)size_t:t(4,2)=(0,4)wchar_t:t(4,3)=(0,3)wint_t:t(4,4)=(0,4)/usr/include/memory.h/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/math.h/usr/include/bits/huge_val.h/usr/include/bits/mathcalls.h :T(27,1)=e_IEEE_:-1,_SVID_:0,_XOPEN_:1,\_POSIX_:2,_ISOC_:3,;_LIB_VERSION_TYPE:t(27,2)=(27,1)exception:T(27,3)=s32type:(0,1),0,32;name:(12,35),32,32;\arg1:(0,13),64,64;arg2:(0,13),128,64;retval:(0,13),192,64;;/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/float.h/usr/include/bits/mathinline.hsocklen_t:t(48,1)=(0,4)__socket_type:T(48,2)=eSOCK_STREAM:1,SOCK_DGRAM:2,\sockaddr:T(48,3)=s16sa_family:(50,1),0,16;sa_data:(48,4)=ar(0,0);0;13;(0,2),16,112;; :T(48,5)=eMSG_OOB:1,MSG_PEEK:2,MSG_DONTROUTE:4,\msghdr:T(48,6)=s28msg_name:(11,2),0,32;msg_namelen:(48,1),32,32;\msg_iov:(48,7)=*(48,8)=xsiovec:,64,32;msg_iovlen:(4,2),96,32;\msg_control:(11,2),128,32;msg_controllen:(4,2),160,32;\cmsghdr:T(48,9)=s12cmsg_len:(4,2),0,32;cmsg_level:(0,1),32,32;\cmsg_type:(0,1),64,32;__cmsg_data:(48,10)=ar(0,0);0;-1;(0,11),96,0;; :T(48,11)=eSCM_RIGHTS:1,__SCM_CREDENTIALS:2,__SCM_CONNECT:3,;linger:T(48,12)=s8l_onoff:(0,1),0,32;l_linger:(0,1),32,32;;/usr/include/sys/uio.h/usr/include/bits/uio.hiovec:T(48,8)=s8iov_base:(11,2),0,32;iov_len:(4,2),32,32;;/usr/include/sys/fcntl.h/usr/include/stropts.h/usr/include/bits/stropts.hbandinfo:T(110,1)=s8bi_pri:(0,11),0,8;bi_flag:(0,1),32,32;;strbuf:T(110,2)=s12maxlen:(0,1),0,32;len:(0,1),32,32;\buf:(12,35),64,32;;strpeek:T(110,3)=s28ctlbuf:(110,2),0,96;databuf:(110,2),96,96;\flags:(12,54),192,32;;strfdinsert:T(110,4)=s36ctlbuf:(110,2),0,96;databuf:(110,2),96,96;\flags:(12,54),192,32;fildes:(0,1),224,32;offset:(0,1),256,32;;strioctl:T(110,5)=s16ic_cmd:(0,1),0,32;ic_timout:(0,1),32,32;\ic_len:(0,1),64,32;ic_dp:(12,35),96,32;;strrecvfd:T(110,6)=s12fd:(0,1),0,32;uid:(12,18),32,32;\gid:(12,19),64,32;;str_mlist:T(110,7)=s256l_name:(110,8)=ar(0,0);0;255;(0,2),0,2048;;str_list:T(110,9)=s8sl_nmods:(0,1),0,32;sl_modlist:(110,10)=*(110,7),32,32;;__res_state:T(120,1)=s512retrans:(0,1),0,32;retry:(0,1),32,32;\options:(36,4),64,32;nscount:(0,1),96,32;nsaddr_list:(120,2)=ar(0,0);0;2;(59,10),128,384;\id:(36,2),512,16;dnsrch:(120,3)=ar(0,0);0;6;(12,35),544,224;\defdname:(110,8),768,2048;pfcode:(36,4),2816,32;ndots:(0,4),2848,4;\nsort:(0,4),2852,4;unused:(120,4)=ar(0,0);0;2;(0,2),2856,24;\sort_list:(120,5)=ar(0,0);0;9;(120,6)=s8addr:(59,3),0,32;\mask:(36,31),32,32;;,2880,640;pad:(120,7)=ar(0,0);0;71;(0,2),3520,576;; :T(120,8)=eres_goahead:0,res_nextns:1,res_modified:2,\res_sendhookact:t(120,9)=(120,8)res_send_qhook:t(120,10)=(120,11)=*(120,12)=f(120,9)res_send_rhook:t(120,13)=(120,14)=*(120,15)=f(120,9)res_sym:T(120,16)=s12number:(0,1),0,32;name:(12,35),32,32;\humanname:(12,35),64,32;;XPointer:t(124,1)=(12,35)_XExtData:T(124,2)=s16number:(0,1),0,32;next:(124,3)=*(124,2),32,32;\free_private:(124,4)=*(124,5)=f(0,1),64,32;private_data:(124,1),96,32;;XExtData:t(124,6)=(124,2)XExtCodes:t(124,7)=(124,8)=s16extension:(0,1),0,32;major_opcode:(0,1),32,32;\XPixmapFormatValues:t(124,9)=(124,10)=s12depth:(0,1),0,32;\XGCValues:t(124,11)=(124,12)=s92function:(0,1),0,32;plane_mask:(0,5),32,32;\arc_mode:(0,1),320,32;tile:(125,9),352,32;stipple:(125,9),384,32;\font:(125,8),480,32;subwindow_mode:(0,1),512,32;\clip_y_origin:(0,1),608,32;clip_mask:(125,9),640,32;\GC:t(124,13)=(124,14)=*(124,15)=xs_XGC:Visual:t(124,16)=(124,17)=s32ext_data:(124,18)=*(124,6),0,32;\visualid:(125,4),32,32;class:(0,1),64,32;red_mask:(0,5),96,32;\Depth:t(124,19)=(124,20)=s12depth:(0,1),0,32;nvisuals:(0,1),32,32;\visuals:(124,21)=*(124,16),64,32;;Screen:t(124,22)=(124,23)=s80ext_data:(124,18),0,32;display:(124,24)=*(124,25)=xs_XDisplay:,32,32;\root:(125,6),64,32;width:(0,1),96,32;height:(0,1),128,32;\depths:(124,26)=*(124,19),256,32;root_depth:(0,1),288,32;\root_visual:(124,21),320,32;default_gc:(124,13),352,32;\cmap:(125,11),384,32;white_pixel:(0,5),416,32;black_pixel:(0,5),448,32;\ScreenFormat:t(124,27)=(124,28)=s16ext_data:(124,18),0,32;\XSetWindowAttributes:t(124,29)=(124,30)=s60background_pixmap:(125,9),0,32;\background_pixel:(0,5),32,32;border_pixmap:(125,9),64,32;\colormap:(125,11),416,32;cursor:(125,10),448,32;;XWindowAttributes:t(124,31)=(124,32)=s92x:(0,1),0,32;y:(0,1),32,32;\depth:(0,1),160,32;visual:(124,21),192,32;root:(125,6),224,32;\colormap:(125,11),480,32;map_installed:(0,1),512,32;\override_redirect:(0,1),672,32;screen:(124,33)=*(124,22),704,32;;XHostAddress:t(124,34)=(124,35)=s12family:(0,1),0,32;length:(0,1),32,32;\address:(12,35),64,32;;funcs:T(124,36)=s24create_image:(124,37)=*(124,38)=f(124,39)=*(124,40)=xs_XImage:,0,32;\destroy_image:(124,41)=*(124,42)=f(0,1),32,32;get_pixel:(124,43)=*(124,44)=f(0,5),64,32;\put_pixel:(124,45)=*(124,46)=f(0,1),96,32;sub_image:(124,47)=*(124,48)=f(124,39),128,32;\add_pixel:(124,49)=*(124,50)=f(0,1),160,32;;_XImage:T(124,40)=s88width:(0,1),0,32;height:(0,1),32,32;\xoffset:(0,1),64,32;format:(0,1),96,32;data:(12,35),128,32;\obdata:(124,1),480,32;f:(124,36),512,192;;XImage:t(124,51)=(124,40)XWindowChanges:t(124,52)=(124,53)=s28x:(0,1),0,32;y:(0,1),32,32;\sibling:(125,6),160,32;stack_mode:(0,1),192,32;;XColor:t(124,54)=(124,55)=s12pixel:(0,5),0,32;red:(0,9),32,16;\XSegment:t(124,56)=(124,57)=s8x1:(0,8),0,16;y1:(0,8),16,16;\XPoint:t(124,58)=(124,59)=s4x:(0,8),0,16;y:(0,8),16,16;;XRectangle:t(124,60)=(124,61)=s8x:(0,8),0,16;y:(0,8),16,16;\XArc:t(124,62)=(124,63)=s12x:(0,8),0,16;y:(0,8),16,16;\XKeyboardControl:t(124,64)=(124,65)=s32key_click_percent:(0,1),0,32;\XKeyboardState:t(124,66)=(124,67)=s56key_click_percent:(0,1),0,32;\global_auto_repeat:(0,1),160,32;auto_repeats:(124,68)=ar(0,0);0;31;(0,2),192,256;;XTimeCoord:t(124,69)=(124,70)=s8time:(125,5),0,32;x:(0,8),32,16;\XModifierKeymap:t(124,71)=(124,72)=s8max_keypermod:(0,1),0,32;\modifiermap:(124,73)=*(125,14),32,32;;Display:t(124,74)=(124,25)_XPrivDisplay:t(124,75)=(124,76)=*(124,77)=s176ext_data:(124,18),0,32;\private1:(124,78)=*(124,79)=xs_XPrivate:,32,32;fd:(0,1),64,32;\proto_minor_version:(0,1),160,32;vendor:(12,35),192,32;\private3:(125,1),224,32;private4:(125,1),256,32;private5:(125,1),288,32;\private6:(0,1),320,32;resource_alloc:(124,80)=*(124,81)=f(125,1),352,32;\nformats:(0,1),512,32;pixmap_format:(124,82)=*(124,27),544,32;\private8:(0,1),576,32;release:(0,1),608,32;private9:(124,78),640,32;\private10:(124,78),672,32;qlen:(0,1),704,32;last_request_read:(0,5),736,32;\request:(0,5),768,32;private11:(124,1),800,32;private12:(124,1),832,32;\private13:(124,1),864,32;private14:(124,1),896,32;\max_request_size:(0,4),928,32;db:(124,83)=*(124,84)=xs_XrmHashBucketRec:,960,32;\private15:(124,85)=*(124,86)=f(0,1),992,32;display_name:(12,35),1024,32;\screens:(124,33),1120,32;motion_buffer:(0,5),1152,32;\max_keycode:(0,1),1248,32;private17:(124,1),1280,32;\private18:(124,1),1312,32;private19:(0,1),1344,32;\xdefaults:(12,35),1376,32;;XKeyEvent:t(124,87)=(124,88)=s60type:(0,1),0,32;serial:(0,5),32,32;\send_event:(0,1),64,32;display:(124,89)=*(124,74),96,32;\window:(125,6),128,32;root:(125,6),160,32;subwindow:(125,6),192,32;\time:(125,5),224,32;x:(0,1),256,32;y:(0,1),288,32;\XKeyPressedEvent:t(124,90)=(124,87)XKeyReleasedEvent:t(124,91)=(124,87)XButtonEvent:t(124,92)=(124,93)=s60type:(0,1),0,32;serial:(0,5),32,32;\send_event:(0,1),64,32;display:(124,89),96,32;\XButtonPressedEvent:t(124,94)=(124,92)XButtonReleasedEvent:t(124,95)=(124,92)XMotionEvent:t(124,96)=(124,97)=s60type:(0,1),0,32;serial:(0,5),32,32;\XPointerMovedEvent:t(124,98)=(124,96)XCrossingEvent:t(124,99)=(124,100)=s68type:(0,1),0,32;serial:(0,5),32,32;\XEnterWindowEvent:t(124,101)=(124,99)XLeaveWindowEvent:t(124,102)=(124,99)XFocusChangeEvent:t(124,103)=(124,104)=s28type:(0,1),0,32;\serial:(0,5),32,32;send_event:(0,1),64,32;display:(124,89),96,32;\window:(125,6),128,32;mode:(0,1),160,32;detail:(0,1),192,32;;XFocusInEvent:t(124,105)=(124,103)XFocusOutEvent:t(124,106)=(124,103)XKeymapEvent:t(124,107)=(124,108)=s52type:(0,1),0,32;serial:(0,5),32,32;\window:(125,6),128,32;key_vector:(124,68),160,256;;XExposeEvent:t(124,109)=(124,110)=s40type:(0,1),0,32;serial:(0,5),32,32;\window:(125,6),128,32;x:(0,1),160,32;y:(0,1),192,32;\XGraphicsExposeEvent:t(124,111)=(124,112)=s48type:(0,1),0,32;\drawable:(125,7),128,32;x:(0,1),160,32;y:(0,1),192,32;\XNoExposeEvent:t(124,113)=(124,114)=s28type:(0,1),0,32;serial:(0,5),32,32;\drawable:(125,7),128,32;major_code:(0,1),160,32;\XVisibilityEvent:t(124,115)=(124,116)=s24type:(0,1),0,32;\window:(125,6),128,32;state:(0,1),160,32;;XCreateWindowEvent:t(124,117)=(124,118)=s48type:(0,1),0,32;\parent:(125,6),128,32;window:(125,6),160,32;x:(0,1),192,32;\XDestroyWindowEvent:t(124,119)=(124,120)=s24type:(0,1),0,32;\event:(125,6),128,32;window:(125,6),160,32;;XUnmapEvent:t(124,121)=(124,122)=s28type:(0,1),0,32;serial:(0,5),32,32;\event:(125,6),128,32;window:(125,6),160,32;from_configure:(0,1),192,32;;XMapEvent:t(124,123)=(124,124)=s28type:(0,1),0,32;serial:(0,5),32,32;\event:(125,6),128,32;window:(125,6),160,32;override_redirect:(0,1),192,32;;XMapRequestEvent:t(124,125)=(124,126)=s24type:(0,1),0,32;\parent:(125,6),128,32;window:(125,6),160,32;;XReparentEvent:t(124,127)=(124,128)=s40type:(0,1),0,32;serial:(0,5),32,32;\event:(125,6),128,32;window:(125,6),160,32;parent:(125,6),192,32;\XConfigureEvent:t(124,129)=(124,130)=s52type:(0,1),0,32;serial:(0,5),32,32;\event:(125,6),128,32;window:(125,6),160,32;x:(0,1),192,32;\border_width:(0,1),320,32;above:(125,6),352,32;\XGravityEvent:t(124,131)=(124,132)=s32type:(0,1),0,32;serial:(0,5),32,32;\XResizeRequestEvent:t(124,133)=(124,134)=s28type:(0,1),0,32;\window:(125,6),128,32;width:(0,1),160,32;height:(0,1),192,32;;XConfigureRequestEvent:t(124,135)=(124,136)=s56type:(0,1),0,32;\XCirculateEvent:t(124,137)=(124,138)=s28type:(0,1),0,32;serial:(0,5),32,32;\event:(125,6),128,32;window:(125,6),160,32;place:(0,1),192,32;;XCirculateRequestEvent:t(124,139)=(124,140)=s28type:(0,1),0,32;\parent:(125,6),128,32;window:(125,6),160,32;place:(0,1),192,32;;XPropertyEvent:t(124,141)=(124,142)=s32type:(0,1),0,32;serial:(0,5),32,32;\window:(125,6),128,32;atom:(125,3),160,32;time:(125,5),192,32;\XSelectionClearEvent:t(124,143)=(124,144)=s28type:(0,1),0,32;\window:(125,6),128,32;selection:(125,3),160,32;time:(125,5),192,32;;XSelectionRequestEvent:t(124,145)=(124,146)=s40type:(0,1),0,32;\owner:(125,6),128,32;requestor:(125,6),160,32;selection:(125,3),192,32;\target:(125,3),224,32;property:(125,3),256,32;time:(125,5),288,32;;XSelectionEvent:t(124,147)=(124,148)=s36type:(0,1),0,32;serial:(0,5),32,32;\requestor:(125,6),128,32;selection:(125,3),160,32;\target:(125,3),192,32;property:(125,3),224,32;time:(125,5),256,32;;XColormapEvent:t(124,149)=(124,150)=s32type:(0,1),0,32;serial:(0,5),32,32;\window:(125,6),128,32;colormap:(125,11),160,32;new:(0,1),192,32;\XClientMessageEvent:t(124,151)=(124,152)=s48type:(0,1),0,32;\window:(125,6),128,32;message_type:(125,3),160,32;\format:(0,1),192,32;data:(124,153)=u20b:(124,154)=ar(0,0);0;19;(0,2),0,160;\s:(124,155)=ar(0,0);0;9;(0,8),0,160;l:(124,156)=ar(0,0);0;4;(0,3),0,160;;,224,160;;XMappingEvent:t(124,157)=(124,158)=s32type:(0,1),0,32;serial:(0,5),32,32;\window:(125,6),128,32;request:(0,1),160,32;first_keycode:(0,1),192,32;\XErrorEvent:t(124,159)=(124,160)=s20type:(0,1),0,32;display:(124,89),32,32;\resourceid:(125,1),64,32;serial:(0,5),96,32;error_code:(0,11),128,8;\XAnyEvent:t(124,161)=(124,162)=s20type:(0,1),0,32;serial:(0,5),32,32;\window:(125,6),128,32;;_XEvent:T(124,163)=u96type:(0,1),0,32;xany:(124,161),0,160;\xkey:(124,87),0,480;xbutton:(124,92),0,480;xmotion:(124,96),0,480;\xcrossing:(124,99),0,544;xfocus:(124,103),0,224;xexpose:(124,109),0,320;\xgraphicsexpose:(124,111),0,384;xnoexpose:(124,113),0,224;\xvisibility:(124,115),0,192;xcreatewindow:(124,117),0,384;\xdestroywindow:(124,119),0,192;xunmap:(124,121),0,224;\xmap:(124,123),0,224;xmaprequest:(124,125),0,192;xreparent:(124,127),0,320;\xconfigure:(124,129),0,416;xgravity:(124,131),0,256;\xresizerequest:(124,133),0,224;xconfigurerequest:(124,135),0,448;\xcirculate:(124,137),0,224;xcirculaterequest:(124,139),0,224;\xproperty:(124,141),0,256;xselectionclear:(124,143),0,224;\xselectionrequest:(124,145),0,320;xselection:(124,147),0,288;\xcolormap:(124,149),0,256;xclient:(124,151),0,384;xmapping:(124,157),0,256;\xerror:(124,159),0,160;xkeymap:(124,107),0,416;pad:(124,164)=ar(0,0);0;23;(0,3),0,768;;XEvent:t(124,165)=(124,163)XCharStruct:t(124,166)=(124,167)=s12lbearing:(0,8),0,16;rbearing:(0,8),16,16;\XFontProp:t(124,168)=(124,169)=s8name:(125,3),0,32;card32:(0,5),32,32;;XFontStruct:t(124,170)=(124,171)=s80ext_data:(124,18),0,32;fid:(125,8),32,32;\properties:(124,172)=*(124,168),320,32;min_bounds:(124,166),352,96;\max_bounds:(124,166),448,96;per_char:(124,173)=*(124,166),544,32;\XTextItem:t(124,174)=(124,175)=s16chars:(12,35),0,32;nchars:(0,1),32,32;\delta:(0,1),64,32;font:(125,8),96,32;;XChar2b:t(124,176)=(124,177)=s4byte1:(0,11),0,8;byte2:(0,11),8,8;;XTextItem16:t(124,178)=(124,179)=s16chars:(124,180)=*(124,176),0,32;\nchars:(0,1),32,32;delta:(0,1),64,32;font:(125,8),96,32;;XEDataObject:t(124,181)=(124,182)=u4display:(124,89),0,32;gc:(124,13),0,32;\visual:(124,21),0,32;screen:(124,33),0,32;pixmap_format:(124,82),0,32;\font:(124,183)=*(124,170),0,32;;XFontSetExtents:t(124,184)=(124,185)=s16max_ink_extent:(124,60),0,64;\max_logical_extent:(124,60),64,64;;XOM:t(124,186)=(124,187)=*(124,188)=xs_XOM:XOC:t(124,189)=(124,190)=*(124,191)=xs_XOC:XFontSet:t(124,192)=(124,190)XmbTextItem:t(124,193)=(124,194)=s16chars:(12,35),0,32;nchars:(0,1),32,32;\delta:(0,1),64,32;font_set:(124,192),96,32;;XwcTextItem:t(124,195)=(124,196)=s16chars:(124,197)=*(4,3),0,32;\nchars:(0,1),32,32;delta:(0,1),64,32;font_set:(124,192),96,32;;XOMCharSetList:t(124,198)=(124,199)=s8charset_count:(0,1),0,32;\charset_list:(105,2),32,32;; :T(124,200)=eXOMOrientation_LTR_TTB:0,XOMOrientation_RTL_TTB:1,\XOrientation:t(124,201)=(124,200)XOMOrientation:t(124,202)=(124,203)=s8num_orientation:(0,1),0,32;\orientation:(124,204)=*(124,201),32,32;;XOMFontInfo:t(124,205)=(124,206)=s12num_font:(0,1),0,32;font_struct_list:(124,207)=*(124,183),32,32;\font_name_list:(105,2),64,32;;XIM:t(124,208)=(124,209)=*(124,210)=xs_XIM:XIC:t(124,211)=(124,212)=*(124,213)=xs_XIC:XIMProc:t(124,214)=(124,215)=*(124,216)=f(0,19)XICProc:t(124,217)=(124,218)=*(124,219)=f(0,1)XIDProc:t(124,220)=(124,221)=*(124,222)=f(0,19)XIMStyle:t(124,223)=(0,5)XIMStyles:t(124,224)=(124,225)=s8count_styles:(0,9),0,16;\supported_styles:(124,226)=*(124,223),32,32;;XVaNestedList:t(124,227)=(11,2)XIMCallback:t(124,228)=(124,229)=s8client_data:(124,1),0,32;\callback:(124,214),32,32;;XICCallback:t(124,230)=(124,231)=s8client_data:(124,1),0,32;\callback:(124,217),32,32;;XIMFeedback:t(124,232)=(0,5)_XIMText:T(124,233)=s16length:(0,9),0,16;feedback:(124,234)=*(124,232),32,32;\encoding_is_wchar:(0,1),64,32;string:(124,235)=u4multi_byte:(12,35),0,32;\wide_char:(124,197),0,32;;,96,32;;XIMText:t(124,236)=(124,233)XIMPreeditState:t(124,237)=(0,5)_XIMPreeditStateNotifyCallbackStruct:T(124,238)=s4state:(124,237),0,32;;XIMPreeditStateNotifyCallbackStruct:t(124,239)=(124,238)XIMResetState:t(124,240)=(0,5)XIMStringConversionFeedback:t(124,241)=(0,5)_XIMStringConversionText:T(124,242)=s16length:(0,9),0,16;\feedback:(124,243)=*(124,241),32,32;encoding_is_wchar:(0,1),64,32;\string:(124,244)=u4mbs:(12,35),0,32;wcs:(124,197),0,32;;,96,32;;XIMStringConversionText:t(124,245)=(124,242)XIMStringConversionPosition:t(124,246)=(0,9)XIMStringConversionType:t(124,247)=(0,9)XIMStringConversionOperation:t(124,248)=(0,9) :T(124,249)=eXIMForwardChar:0,XIMBackwardChar:1,XIMForwardWord:2,\XIMCaretDirection:t(124,250)=(124,249)_XIMStringConversionCallbackStruct:T(124,251)=s16position:(124,246),0,16;\direction:(124,250),32,32;operation:(124,248),64,16;\factor:(0,9),80,16;text:(124,252)=*(124,245),96,32;;XIMStringConversionCallbackStruct:t(124,253)=(124,251)_XIMPreeditDrawCallbackStruct:T(124,254)=s16caret:(0,1),0,32;\text:(124,255)=*(124,236),96,32;;XIMPreeditDrawCallbackStruct:t(124,256)=(124,254) :T(124,257)=eXIMIsInvisible:0,XIMIsPrimary:1,XIMIsSecondary:2,;XIMCaretStyle:t(124,258)=(124,257)_XIMPreeditCaretCallbackStruct:T(124,259)=s12position:(0,1),0,32;\direction:(124,250),32,32;style:(124,258),64,32;;XIMPreeditCaretCallbackStruct:t(124,260)=(124,259) :T(124,261)=eXIMTextType:0,XIMBitmapType:1,;XIMStatusDataType:t(124,262)=(124,261)_XIMStatusDrawCallbackStruct:T(124,263)=s8type:(124,262),0,32;\data:(124,264)=u4text:(124,255),0,32;bitmap:(125,9),0,32;;,32,32;;XIMStatusDrawCallbackStruct:t(124,265)=(124,263)_XIMHotKeyTrigger:T(124,266)=s12keysym:(125,13),0,32;modifier:(0,1),32,32;\XIMHotKeyTrigger:t(124,267)=(124,266)_XIMHotKeyTriggers:T(124,268)=s8num_hot_key:(0,1),0,32;\key:(124,269)=*(124,267),32,32;;XIMHotKeyTriggers:t(124,270)=(124,268)XIMHotKeyState:t(124,271)=(0,5)XIMValuesList:t(124,272)=(124,273)=s8count_values:(0,9),0,16;\supported_values:(105,2),32,32;;XErrorHandler:t(124,274)=(124,275)=*(124,276)=f(0,1)XIOErrorHandler:t(124,277)=(124,278)=*(124,279)=f(0,1)XConnectionWatchProc:t(124,280)=(124,281)=*(124,282)=f(0,19)sipdata:G(12,35)sipblocks:G(0,1)sipdatalen:G(0,1)debug_tcp_conns:F(0,19)sip_send_udp:F(0,1)dst:P(12,35)ttl:P(0,1)msg:P(12,35)sin:(59,10)sip_send:F(0,1)dst:P(46,12)no_of_socks:V(0,1)slist:V(0,20)=ar(0,0);0;19;(0,3)sockets:V(0,21)=ar(0,0);0;19;(0,1)code:r(0,1)freesock:r(0,1)usedsock:r(0,1)sock:r(0,1)look_up_address:F(59,3)hostname:P(12,35)addr:V(59,3)hostaddr:r(0,22)=*(104,1)str:V(110,8)dotted_decimal:r(0,1)buf:(122,104)ans:(0,23)=ar(0,0);0;999;(0,2)ctr:r(0,1)tstr:r(12,35)resstr:r(12,35)dnsa:(0,24)=*(132,1)tmp:r(0,1)sip_get_dstname:F(12,35)line:r(12,35)cr:r(12,35)url:r(12,35)res:V(12,35)username:r(12,35)hostname:r(12,35)sip_get_method:F(0,1)method:(124,154)is_a_sip_request:F(0,1)is_a_sip_reply:F(0,1)parse_sip_reply:F(0,1)addr:P(12,35)rtype:r(0,2)sip_udp_listen:F(0,1)address:P(12,35)rxsock:r(0,1)name:(59,10)imr:(62,3)sip_tcp_listen:F(0,1)fd:r(0,1)sip_tcp_accept:F(0,1)conns:P(0,25)=*(131,2)addr:(59,10)cnum:r(0,1)addrlen:(0,1)sip_tcp_free:F(0,19)conn:P(0,25)sip_request_ready:F(0,1)buf:P(12,35)clenstr:r(12,35)payload:r(12,35)clen:r(0,1)__nptr:r(71,3)extract_field:F(0,1)field_ret:P(12,35)retlen:P(0,1)field:P(12,35)ptr:r(12,35)ufield:(124,154)flen:r(0,1)extract_parts:F(0,1)method:P(12,35)url:P(12,35)via:P(12,35)rest:p(12,35)j:r(0,1)is_a_sip_url:F(0,1)parse_sip_url:F(0,1)user:P(12,35)passwd:P(12,35)host:P(12,35)port:p(0,26)=*(0,1)transport:p(0,26)ttl:p(0,26)maddr:p(12,35)tag:p(12,35)others:p(12,35)buf:r(12,35)ptr1:r(12,35)ptr2:r(12,35)ptr3:r(12,35)parse_sip_path:F(0,1)path:p(12,35)version:P(12,35)transport:P(0,26)port:p(0,26)sip_send_tcp_request:F(0,1)origfd:P(0,1)host:p(12,35)port:p(0,1)user_data:P(12,35)wait:p(0,1)sinhim:(59,10)addr:r(0,22)len:r(0,1)sipstate:r(0,1)msg:(48,6)iov:(0,27)=ar(0,0);0;9;(48,8)iovlen:r(0,1)r:(41,2)w:(41,2)tv:(73,1)__i:r(0,4)__arr:r(0,28)=*(12,40)__arr:r(0,28)sip_send_tcp_reply:F(0,1)callid:P(12,35)msg:p(12,35)sip_send_tcp_reply_to_fd:F(0,1)sip_finished_reading_tcp:F(0,1)data:P(12,35)contentlen:(124,154)find_end_of_header:F(12,35)sip_generate_callid:F(12,35)callid:V(62,2)pid:r(36,16)../src/sip_register.c../src/ui_fns.h/usr/lib/gcc-lib/arm-linuxelf/2.8.1/include/sys/file.hiovec:T(29,8)=s8iov_base:(8,2),0,32;iov_len:(7,1),32,32;;sip_register:F(0,1)emailaddr:(0,20)=ar(0,0);0;79;(0,2)serverurl:r(9,35)msg:(0,21)=ar(0,0);0;2047;(0,2)send_sip_register:F(0,1)uridata:P(9,35)proxyuri:P(9,35)user_data:P(9,35)transport:(0,1)host:(92,4)maddr:(92,4)url:(92,4)sip_send_mcast_register:F(0,1)host:P(9,35)maddr:P(9,35)user_data:p(9,35)sip_send_udp_register:F(0,1)sip_send_tcp_register:F(0,1)../src/tkUnixInit.cTkPlatformInit:F(0,1)interp:P(0,20)=*(1,5)../src/ui_fns.cui_sd_listen:F(0,1)dummy:P(94,1)interp:P(0,20)=*(94,5)argc:P(0,1)argv:P(62,2)ui_generate_port:F(0,1)interp:P(0,20)ui_generate_id:F(0,1)ui_lookup_host:F(0,1)ui_sip_send_udp:F(0,1)ui_sip_send_tcp_request:F(0,1)ui_sip_send_tcp_reply:F(0,1)ui_set_sipalias:F(0,1)ui_check_address:F(0,1)in:(40,3)ui_generate_address:F(0,1)initnames:F(0,19)base:r(17,3)buf:(33,2)ui_getdayname:F(0,1)mnum:r(0,1)ui_getmonname:F(0,1)ui_getemailaddress:F(0,1)email:V(92,4)ui_getusername:F(0,1)ui_gethostaddr:F(0,1)ui_gethostname:F(0,1)ui_getpid:F(0,1)pids:V(38,3)ui_stop_session_ad:F(0,1)ui_sip_parse_url:F(0,1)interp:p(0,20)addr:(9,35)user:(9,35)passwd:r(9,35)maddr:r(9,35)tag:r(9,35)others:r(9,35)transport_str:(47,3)ui_sip_parse_path:F(0,1)addr:r(9,35)version:r(9,35)ui_sip_close_tcp_connection:F(0,1)ui_run_program:F(0,1)pid:r(0,1)daynames:S(0,21)=ar(0,0);0;6;(94,113)longdaynames:S(0,22)=ar(0,0);0;6;(0,23)=ar(0,0);0;20;(0,2)monnames:S(0,24)=ar(0,0);0;11;(94,113)longmonnames:S(0,25)=ar(0,0);0;11;(0,23)../src/ui_init.c../src/tcl_modules.hmodname:G(118,1)=ar(0,0);0;14;(68,3)modvar:G(118,1)ui_fn_name:G(118,2)=ar(0,0);0;38;(68,3)ui_fn:G(118,3)=ar(0,0);0;38;(8,2)synchronize:S(0,1)fileName:S(9,35)name:S(9,35)display:S(9,35)geometry:S(9,35)argTable:S(0,20)=ar(0,1);0;-1;(95,32)ui_init:F(0,1)argc:P(0,21)=*(0,1)buf:(92,4)announce_error:F(0,1)code:P(0,1)command:P(9,35)ui_create_interface:F(0,1)mainWindow:S(95,25)interp:G(0,22)=*(94,5)command:S(94,105)../src/www_fns.cwebdata:G(9,35)webblocks:G(0,1)stoploading:G(0,1)ui_webto:F(0,1)interp:p(0,20)=*(94,5)uridata:(0,21)=ar(0,0);0;1023;(0,2)uri:r(9,35)end:r(9,35)t1:r(9,35)t2:r(9,35)proto:r(9,35)sinhim:(40,10)addr:r(0,22)=*(61,1)usingproxy:r(0,1)reload:(0,1)webstate:r(0,1)msg:(29,6)iov:(0,23)=ar(0,0);0;5;(29,8)port:r(0,1)file:(92,4)r:(22,2)w:(22,2)__arr:r(0,24)=*(9,40)__arr:r(0,24)err:(0,1)errlen:(0,1)www_perror:f(0,1)who:P(9,35)err:P(0,1)p:r(9,35)ui_save_www_data_to_file:F(0,1)file:r(0,25)=*(2,1)ui_stop_www_loading:F(0,1)webdatalen:G(0,1)../src/cli.cinit_cli:F(0,1)do_cli:F(0,1)clientData:P(1,1)cmd:V(0,20)=ar(0,0);0;255;(0,2)../src/crypt.c../src/crypt.hPOINTER:t(14,1)=(14,2)=*(0,11)UINT2:t(14,3)=(0,9)UINT4:t(14,4)=(0,4)../src/qfDES.hQFDES_what_e:T(15,1)=eqfDES_encrypt:0,qfDES_decrypt:1,;QFDES_what:t(15,2)=(15,1)QFDES_mode_e:T(15,3)=eqfDES_ecb:0,qfDES_cbc:1,\qfDES_cfb:2,qfDES_ofb:3,;QFDES_mode:t(15,4)=(15,3)QFDES_parity_e:T(15,5)=eqfDES_even:0,qfDES_odd:1,;QFDES_parity:t(15,6)=(15,5)QFDES_generate_e:T(15,7)=eqfDES_key:0,qfDES_iv:1,;QFDES_generate:t(15,8)=(15,7)../src/md5.hMD5_CTX:t(16,1)=(16,2)=s88state:(16,3)=ar(0,0);0;3;(14,4),0,128;\count:(16,4)=ar(0,0);0;1;(14,4),128,64;buffer:(16,5)=ar(0,0);0;63;(0,11),192,512;;empty_key:S(1,3)wrkbuf_:G(0,20)=*(1,1)badpktlen_:S(1,3)badpbit_:S(1,3)Null_Key:F(0,1)decrypt:f(0,1)in:P(0,21)=*(1,1)out:P(0,20)pad:r(0,1)initVec:(0,22)=ar(0,0);0;7;(1,1)inpk:r(0,20)install_key:f(0,1)key:P(14,2)Set_Key:F(0,1)key:P(0,23)=*(0,2)hash:(0,24)=ar(0,0);0;15;(1,1)context:(16,1)Encrypt:F(0,20)in:P(0,20)len:P(0,25)=*(0,1)initVec:(0,22)rh:r(0,20)padding:r(0,20)Decrypt:F(0,1)in:P(0,21)des_key:S(0,22)crypt_buffer:G(0,26)=ar(0,0);0;8191;(1,1)../src/md5.cPADDING:S(27,5)MD5Init:F(0,19)context:P(0,20)=*(27,1)MD5Update:F(0,19)context:P(0,20)input:P(26,2)inputLen:P(0,4)index:r(0,4)partLen:r(0,4)MD5Final:F(0,19)digest:P(26,2)bits:(0,21)=ar(0,0);0;7;(0,11)padLen:r(0,4)MD5Transform:f(0,19)state:P(0,22)=*(26,4)block:P(26,2)a:r(26,4)b:r(26,4)c:r(26,4)d:r(26,4)x:(0,23)=ar(0,0);0;15;(26,4)Encode:f(0,19)output:P(26,2)input:P(0,22)len:P(0,4)j:r(0,4)Decode:f(0,19)output:P(0,22)MD5_memcpy:f(0,19)output:P(26,1)input:P(26,1)MD5_memset:f(0,19)value:P(0,1)../src/sap_crypt.cPOINTER:t(116,1)=(95,147)UINT2:t(116,2)=(0,9)UINT4:t(116,3)=(0,4)MD5_CTX:t(117,1)=(117,2)=s88state:(117,3)=ar(0,0);0;3;(116,3),0,128;\count:(117,4)=ar(0,0);0;1;(116,3),128,64;buffer:(117,5)=ar(0,0);0;63;(0,11),192,512;;keytable:S(0,20)=ar(0,1);0;-1;(0,21)=s8key:(0,22)=ar(0,0);0;7;(1,1),0,64;;set_pass_phrase:F(0,1)newphrase:P(6,35)get_pass_phrase:F(6,35)encrypt_announcement:F(0,1)srcbuf:P(6,35)dstbuf:P(62,2)length:P(0,23)=*(0,1)key:P(6,35)parse_privhdr:F(0,1)buf:P(6,35)len:P(0,23)recvkey:P(6,35)priv_hdr:r(14,6)tmpbuf:r(6,35)rc:r(0,1)decrypt_announcement:F(0,1)recvkey:p(6,35)key:(92,4)dstbuf:r(6,35)origbuf:(6,35)tmpkey:r(115,2)get_sdr_home:F(0,1)str:P(6,35)find_keyname_by_key:F(0,1)keyname:P(6,35)find_key_by_name:F(0,1)register_key:F(0,1)delete_key:F(0,1)save_keys:F(0,1)buf:r(6,35)p:r(0,24)=*(115,3)no_of_keys:r(0,1)keyfilename:(92,4)load_keys:F(0,1)delkey:r(115,2)addkey:r(115,2)sbuf:(73,1)buf:(0,25)=*(1,1)p:(0,24)write_crypted_file:F(0,1)afilename:P(6,35)data:p(6,35)len:p(0,1)auth_type:p(6,35)advertid:p(6,35)encbuf:r(6,35)p:r(6,35)file:r(0,26)=*(15,1)tmpfilename:(92,4)context:(117,1)hash:(0,27)=ar(0,0);0;15;(1,1)bplen:r(0,1)addata:(14,8)authinfo:r(14,2)bp:r(14,4)filename:(6,35)load_crypted_file:F(0,1)buf:p(6,35)file:r(0,26)correct:r(0,1)hash:(0,28)=ar(0,0);0;15;(1,1)encbuf:r(0,25)clearbuf:r(0,25)make_random_key:F(0,1)hash:(0,29)=ar(0,0);0;15;(1,1)seed:(0,1)havegoodkey:r(0,1)key:r(6,35)newkey:(6,35)getseed:f(0,1)prid:r(0,1)seed:r(0,1)curtime:(7,1)goodkey:f(0,1)seed:P(0,23)isgoodkey:f(0,1)ToBase64:F(0,1)inbp:P(0,30)=*(95,147)ilen:P(0,23)outbuff:P(6,35)olen:P(0,1)bp:r(95,147)count:r(0,1)Base64:V(0,31)=ar(0,0);0;64;(0,2)val:r(0,5)bin_to_b64_aux:F(0,1)in:p(0,25)inlen:p(0,1)cpp:P(62,2)nc:r(0,1)b64len:r(0,1)cp:r(6,35)keylist:G(115,2)passphrase:G(92,4)../src/qfDES.cwchar_t:t(16,1)=(0,3)socklen_t:t(17,1)=(0,4)__socket_type:T(17,2)=eSOCK_STREAM:1,SOCK_DGRAM:2,\sockaddr:T(17,3)=s16sa_family:(19,1),0,16;sa_data:(17,4)=ar(0,0);0;13;(0,2),16,112;; :T(17,5)=eMSG_OOB:1,MSG_PEEK:2,MSG_DONTROUTE:4,\msghdr:T(17,6)=s28msg_name:(17,7)=*(0,19),0,32;msg_namelen:(17,1),32,32;\msg_iov:(17,8)=*(17,9)=xsiovec:,64,32;msg_iovlen:(8,1),96,32;\msg_control:(17,7),128,32;msg_controllen:(8,1),160,32;\cmsghdr:T(17,10)=s12cmsg_len:(8,1),0,32;cmsg_level:(0,1),32,32;\cmsg_type:(0,1),64,32;__cmsg_data:(17,11)=ar(0,0);0;-1;(0,11),96,0;; :T(17,12)=eSCM_RIGHTS:1,__SCM_CREDENTIALS:2,__SCM_CONNECT:3,;linger:T(17,13)=s8l_onoff:(0,1),0,32;l_linger:(0,1),32,32;;Word:t(0,20)=(0,5)../src/qfDES_aux.hs_p0:S(24,1)=ar(0,0);0;63;(0,20)s_p1:S(24,1)s_p2:S(24,1)s_p3:S(24,1)s_p4:S(24,1)s_p5:S(24,1)s_p6:S(24,1)s_p7:S(24,1)G_padChar:G(0,2)rol:S(0,21)=ar(0,0);0;15;(0,22)=ar(0,0);0;2;(0,20)ror:S(0,21)qfDES:F(0,1)key:p(6,35)size:p(0,4)what:p(23,2)mode:p(23,4)initVec:p(6,35)mode:r(23,4)desKey:V(0,23)=ar(0,0);0;7;(0,2)desKeys:V(0,24)=ar(0,0);0;127;(0,2)oldKey:V(0,25)=*(0,20)keys:V(0,25)oldWhat:V(23,2)oldMode:V(23,4)b0:(0,26)=ar(0,0);0;7;(0,2)b1:(0,27)=ar(0,0);0;7;(0,2)newKey:r(0,25)text:r(0,25)cb:r(0,25)cb1:(0,25)origSize:(0,4)z:r(0,4)l:r(0,4)tp:r(0,25)c:r(0,20)d:r(0,20)z:r(0,1)rl:r(0,25)k:r(0,25)rr:r(0,25)ik1:r(0,25)ik2:r(0,25)ik3:r(0,28)=ar(0,0);0;1;(0,20)l:r(0,20)r:r(0,20)reg32:r(0,20)round:r(0,20)bb:r(6,35)w:r(0,20)../src/polluted.cinit_security:F(0,1)aux_load_file:F(0,1)name:P(9,35)flag:P(9,35)cache:r(0,20)=*(2,1)parse_announcement:F(0,1)enc:P(0,1)data:P(9,35)src:P(0,5)addr:p(9,35)sec:p(0,1)hfrom:r(0,5)recvkey:(92,4)build_packet:F(0,1)adstr:P(9,35)encrypt:P(0,1)bp:r(1,4)len_add:r(0,1)privlen:r(0,1)add_privacy_header:F(0,1)auth_len:P(0,1)priv_hdr:r(1,6)padlen:r(0,1)store_data_to_announce:F(0,1)addata:P(1,8)keyname:P(9,35)encdata:(9,35)ui_createsession:F(0,1)interp:P(0,21)=*(94,5)endtime:(0,1)aid:(0,22)=ar(0,0);0;79;(0,2)tempptr:(9,35)addata:r(1,8)data:(0,23)=ar(0,0);0;2047;(0,2)authstatus:(29,4)encstatus:(29,4)authmessage:(0,25)=ar(0,0);0;399;(0,2)encmessage:(0,26)=ar(0,0);0;399;(0,2)new_len:(0,1)ui_quit:F(0,1)ui_set_passphrase:F(0,1)interp:P(0,21)ui_get_passphrase:F(0,1)ui_write_crypted_file:F(0,1)ui_write_authentication:F(0,1)ui_write_encryption:F(0,1)ui_add_key:F(0,1)ui_delete_key:F(0,1)ui_load_keys:F(0,1)ui_save_keys:F(0,1)ui_make_random_key:F(0,1)ui_find_key_by_name:F(0,1)ui_find_keyname_by_key:F(0,1)keyname:(92,4)gen_new_data:F(0,1)new_data:p(9,35)file:r(0,20)homedir:r(9,35)testname:(92,4)buf:r(9,35)newlen:r(0,1)authinfo:r(1,2)sapenc_p:r(1,6)gen_new_auth_data:F(0,1)buf:p(9,35)bp:P(1,4)enc:p(0,1)newbuf:r(9,35)sbuf:r(9,35)bp1:r(1,4)gen_new_cache_data:F(0,1)new_data:P(9,35)data_len:P(0,1)enc:r(0,1)../src/pgp_crypt.cauthtxt_fname:G(7,35)authsig_fname:G(7,35)authkey_fname:G(7,35)enctxt_fname:G(7,35)sapenc_fname:G(7,35)generate_authentication_info:F(0,1)data:P(7,35)authstatus:p(7,35)irand:P(0,1)authmessage:p(7,35)authmessagelen:p(0,1)auth_fd:r(0,20)=*(16,1)homedir:r(7,35)fulltxt:r(7,35)irandstr:r(7,35)auth_message:r(7,35)check_authentication:F(7,35)auth_p:p(0,21)=*(15,9)authinfo:P(7,35)data:p(7,35)data_len:p(0,1)auth_len:p(0,1)asym_keyid:p(7,35)irand:p(0,1)sig_fd:r(0,20)key_fd:r(0,20)auth_fd:r(0,20)sig_len:r(0,1)key_len:r(0,1)pad_len:r(0,1)key_id:r(7,35)auth_status:r(7,35)fulltxt:(7,35)fullsig:r(7,35)fullkey:(7,35)store_authentication_in_memory:F(0,1)addata:P(15,8)auth_type:P(7,35)sbuf:(74,1)sbufk:(74,1)authinfo:r(15,2)keycert:r(7,35)irandstr:(7,35)encsig:r(7,35)test_len:r(0,1)__path:r(69,3)__path:(69,3)generate_encryption_info:F(0,1)encstatus:p(7,35)encmessage:p(7,35)encmessagelen:p(0,1)enc_fd:r(0,20)encfulltxt:r(7,35)encfullenc:r(7,35)enc_message:r(7,35)check_encryption:F(7,35)enc_p:P(15,6)encinfo:p(7,35)hdr_len:p(0,1)enc_asym_keyid:p(7,35)irand:r(0,1)enc_status_p:r(7,35)enc_status:r(7,35)encfulltxt:(7,35)encfullenc:(7,35)store_encryption_in_memory:F(0,1)enc_type:P(7,35)sbufd:(74,1)encbuf:r(7,35)ac:r(7,35)sapenc_p:r(15,6)decrypt:r(7,35)../src/pkcs7_crypt.cx509txt_fname:G(6,35)x509sig_fname:G(6,35)x509key_fname:G(6,35)x509bdy_fname:G(6,35)sx509txt_fname:G(6,35)sx509enc_fname:G(6,35)generate_x509_authentication_info:F(0,1)data:P(6,35)authstatus:P(6,35)authmessage:p(6,35)txt_fd:r(0,20)=*(15,1)homedir:r(6,35)fulltxt:(92,4)irandstr:(0,21)=ar(0,0);0;9;(0,2)auth_message:r(6,35)check_x509_authentication:F(6,35)auth_p:P(0,22)=*(14,9)authinfo:P(6,35)asym_keyid:p(6,35)key_id:r(6,35)auth_status:r(6,35)fullsig:(92,4)fullbdy:(92,4)irandstr:(0,23)=ar(0,0);0;9;(0,2)store_x509_authentication_in_memory:F(0,1)addata:P(14,8)encsig:r(6,35)irandstr:(0,24)=ar(0,0);0;9;(0,2)generate_x509_encryption_info:F(0,1)encstatus:p(6,35)encmessage:P(6,35)txt_fd:r(0,20)sx509fulltxt:(92,4)sx509fullenc:(92,4)irandstr:(0,25)=ar(0,0);0;9;(0,2)enc_message:r(6,35)check_x509_encryption:F(6,35)enc_p:P(14,6)encinfo:P(6,35)enc_asym_keyid:p(6,35)encmessage:p(6,35)enc_status:r(6,35)irandstr:(0,26)=ar(0,0);0;9;(0,2)store_x509_encryption_in_memory:F(0,1)enc_type:P(6,35)sbufd:(73,1)ac:r(6,35)sapenc_p:r(14,6)decrypt:r(6,35)irandstr:(0,27)=ar(0,0);0;9;(0,2)tcl_generic.ctcl_generic:G(0,20)=ar(0,0);0;17932;(0,2)tcl_www.ctcl_www:G(0,20)=ar(0,0);0;32696;(0,2)tcl_new.ctcl_new:G(0,20)=ar(0,0);0;83547;(0,2)tcl_start_tools.ctcl_start_tools:G(0,20)=ar(0,0);0;2993;(0,2)tcl_parsed_plugins.ctcl_parsed_plugins:G(0,20)=ar(0,0);0;28978;(0,2)tcl_plugins.ctcl_plugins:G(0,20)=ar(0,0);0;35912;(0,2)tcl_sip.ctcl_sip:G(0,20)=ar(0,0);0;68588;(0,2)tcl_sdp.ctcl_sdp:G(0,20)=ar(0,0);0;6084;(0,2)tcl_sdr.ctcl_sdr:G(0,20)=ar(0,0);0;147879;(0,2)tcl_cache.ctcl_cache:G(0,20)=ar(0,0);0;6061;(0,2)tcl_cli.ctcl_cli:G(0,20)=ar(0,0);0;15500;(0,2)tcl_sap_crypt.ctcl_sap_crypt:G(0,20)=ar(0,0);0;36715;(0,2)tcl_pgp_crypt.ctcl_pgp_crypt:G(0,20)=ar(0,0);0;78097;(0,2)tcl_pkcs7_crypt.ctcl_pkcs7_crypt:G(0,20)=ar(0,0);0;49541;(0,2)/home/scottb/projects/gcc-2.8.1/./libgcc2.ctconfig.hconfig/arm/xm-linux.hconfig/arm/xm-arm.htm.hconfig/arm/linux-elf.hconfig/arm/elf-svr4.hconfig/svr4.hconfig/arm/elf.hconfig/arm/arm.harm_cond_code:T(9,1)=eARM_EQ:0,ARM_NE:1,ARM_CS:2,\ARM_CC:3,ARM_MI:4,ARM_PL:5,ARM_VS:6,\ARM_VC:7,ARM_HI:8,ARM_LS:9,ARM_GE:10,\ARM_LT:11,ARM_GT:12,ARM_LE:13,ARM_AL:14,\ARM_NV:15,;arm_cpu_select:T(9,2)=s16string:(9,3)=*(0,2),0,32;\name:(9,3),32,32;set_tune_p:(0,1),64,32;set_arch_p:(0,1),96,32;;processor_type:T(9,4)=ePROCESSOR_ARM2:0,PROCESSOR_ARM3:1,\PROCESSOR_ARM6:2,PROCESSOR_ARM7:3,PROCESSOR_ARM8:4,\PROCESSOR_STARM:5,PROCESSOR_NONE:6,;prog_mode_type:T(9,5)=eprog_mode26:0,prog_mode32:1,;floating_point_type:T(9,6)=eFP_HARD:0,FP_SOFT2:1,\FP_SOFT3:2,;reg_class:T(9,7)=eNO_REGS:0,FPU_REGS:1,GENERAL_REGS:2,\ALL_REGS:3,LIM_REG_CLASSES:4,;/usr/include/asm/unistd.h/usr/include/asm/mman.hconfig/xm-linux.hmachmode.hgansidecl.hmachmode.defmachine_mode:T(14,1)=eVOIDmode:0,PQImode:1,QImode:2,\PHImode:3,HImode:4,PSImode:5,SImode:6,\PDImode:7,DImode:8,TImode:9,OImode:10,\QFmode:11,HFmode:12,TQFmode:13,SFmode:14,\DFmode:15,XFmode:16,TFmode:17,QCmode:18,\HCmode:19,SCmode:20,DCmode:21,XCmode:22,\TCmode:23,CQImode:24,CHImode:25,CSImode:26,\CDImode:27,CTImode:28,COImode:29,\BLKmode:30,CCmode:31,CC_NOOVmode:32,\CC_Zmode:33,CC_SWPmode:34,CCFPmode:35,\CCFPEmode:36,CC_DNEmode:37,CC_DEQmode:38,\CC_DLEmode:39,CC_DLTmode:40,CC_DGEmode:41,\CC_DGTmode:42,CC_DLEUmode:43,CC_DLTUmode:44,\CC_DGEUmode:45,CC_DGTUmode:46,CC_Cmode:47,\MAX_MACHINE_MODE:48,;mode_class:T(14,2)=eMODE_RANDOM:0,MODE_INT:1,MODE_FLOAT:2,\MODE_PARTIAL_INT:3,MODE_CC:4,MODE_COMPLEX_INT:5,\MODE_COMPLEX_FLOAT:6,MAX_MODE_CLASS:7,;defaults.hinclude/stddef.hptrdiff_t:t(18,1)=(0,1)size_t:t(18,2)=(0,4)wchar_t:t(18,3)=(0,3)wint_t:t(18,4)=(0,4)UQItype:t(0,20)=(0,11)SItype:t(0,21)=(0,1)USItype:t(0,22)=(0,4)DItype:t(0,23)=(0,6)UDItype:t(0,24)=(0,7)SFtype:t(0,25)=(0,12)DFtype:t(0,26)=(0,13)word_type:t(0,27)=(0,1)DIstruct:T(0,28)=s8low:(0,21),0,32;high:(0,21),32,32;;DIunion:t(0,29)=(0,30)=u8s:(0,28),0,64;ll:(0,23),0,64;;include/stdio.hinclude/stdarg.h__gnuc_va_list:t(25,1)=(25,2)=*(0,19)__u_char:t(26,1)=(0,11)__u_short:t(26,2)=(0,9)__u_int:t(26,3)=(0,4)__u_long:t(26,4)=(0,5)__u_quad_t:t(26,5)=(0,7)__quad_t:t(26,6)=(0,6)__int8_t:t(26,7)=(0,10)__uint8_t:t(26,8)=(0,11)__int16_t:t(26,9)=(0,8)__uint16_t:t(26,10)=(0,9)__int32_t:t(26,11)=(0,1)__uint32_t:t(26,12)=(0,4)__int64_t:t(26,13)=(0,6)__uint64_t:t(26,14)=(0,7)__qaddr_t:t(26,15)=(26,16)=*(26,6)__dev_t:t(26,17)=(26,5)__uid_t:t(26,18)=(26,3)__gid_t:t(26,19)=(26,3)__ino_t:t(26,20)=(26,4)__mode_t:t(26,21)=(26,3)__nlink_t:t(26,22)=(26,3)__off_t:t(26,23)=(0,3)__loff_t:t(26,24)=(26,6)__pid_t:t(26,25)=(0,1)__ssize_t:t(26,26)=(0,1)__rlim_t:t(26,27)=(0,3)__rlim64_t:t(26,28)=(26,6)__id_t:t(26,29)=(26,3)__fsid_t:t(26,30)=(26,31)=s8__val:(26,32)=ar(0,0);0;1;(0,1),0,64;;__daddr_t:t(26,33)=(0,1)__caddr_t:t(26,34)=(9,3)__time_t:t(26,35)=(0,3)__swblk_t:t(26,36)=(0,3)__clock_t:t(26,37)=(0,3)__fd_mask:t(26,38)=(0,5)__fd_set:t(26,39)=(26,40)=s128fds_bits:(26,41)=ar(0,0);0;31;(26,38),0,1024;;__key_t:t(26,42)=(0,1)__ipc_pid_t:t(26,43)=(0,9)__blkcnt_t:t(26,44)=(26,4)__blkcnt64_t:t(26,45)=(26,5)__fsblkcnt_t:t(26,46)=(0,3)__fsblkcnt64_t:t(26,47)=(26,6)__fsfilcnt_t:t(26,48)=(26,4)__fsfilcnt64_t:t(26,49)=(26,5)__ino64_t:t(26,50)=(26,4)__off64_t:t(26,51)=(26,24)__t_scalar_t:t(26,52)=(0,1)__t_uscalar_t:t(26,53)=(0,4)FILE:t(19,1)=(19,2)=xs_IO_FILE:_IO_lock_t:t(27,1)=(0,19)_IO_marker:T(27,2)=s12_next:(27,3)=*(27,2),0,32;_sbuf:(27,4)=*(19,2),32,32;\_IO_FILE:T(19,2)=s148_flags:(0,1),0,32;_IO_read_ptr:(9,3),32,32;\_IO_read_end:(9,3),64,32;_IO_read_base:(9,3),96,32;\_IO_write_base:(9,3),128,32;_IO_write_ptr:(9,3),160,32;\_IO_write_end:(9,3),192,32;_IO_buf_base:(9,3),224,32;\_IO_buf_end:(9,3),256,32;_IO_save_base:(9,3),288,32;\_IO_backup_base:(9,3),320,32;_IO_save_end:(9,3),352,32;\_markers:(27,3),384,32;_chain:(27,4),416,32;_fileno:(0,1),448,32;\_blksize:(0,1),480,32;_old_offset:(26,23),512,32;\_shortbuf:(27,5)=ar(0,0);0;0;(0,2),568,8;_lock:(27,6)=*(27,1),576,32;\_offset:(26,51),608,64;_unused2:(27,7)=ar(0,0);0;15;(0,1),672,512;;_IO_FILE:t(27,8)=(19,2)_IO_cookie_io_functions_t:t(27,9)=(27,10)=s16read:(27,11)=*(27,12)=f(26,26),0,32;\write:(27,13)=*(27,14)=f(26,26),32,32;seek:(27,15)=*(27,16)=f(26,23),64,32;\close:(27,17)=*(27,18)=f(0,1),96,32;;_IO_cookie_file:T(27,19)=s172file:(19,2),0,1184;vtable:(27,20)=*(0,19),1184,32;\cookie:(25,2),1216,32;io_functions:(27,9),1248,128;;fpos_t:t(19,3)=(26,23)__eprintf:F(0,19)string:P(0,31)=*(0,2)expression:P(0,31)line:P(0,1)filename:P(0,31)GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1GCC: (GNU) 2.8.1.symtab.strtab.shstrtab.interp.note.ABI-tag.hash.dynsym.dynstr.rel.got.rel.bss.rel.plt.init.plt.text.fini.rodata.data.ctors.dtors.got.dynamic.bss.stab.stabstr.comment# 1007 ?  6G P 0Y 44H b||<hmXXos<<yPPDG S  t&z  z  z  {  |  tT  D Q-40X5| (6d0 4|  X < P S z z z { |     #-G  0L T \ԋ kԋ $   ( z , z z \ S z       S z L S  S  S +S :S  E T  Q*U  ]JV  ijW  uX  X  X  X   Y  *Y  JY  jY  Y  Z  @Z VZ lZ  Z  Z  Z B&[  6.[  DN[  On[  XT ]\ bd gl lx q v {        Č ̌ Ԍ ،         $ , 4     < \    $ ) .$ 4D :d @ F L R X ^$ dD jh p v |    ,  L  l        ! T! L! ( X8 ]H ! ! ! ! H" " "  " " $" )(" .4" 4@" :D" \" bx g l q v {č @\" Ft" L|" p# " R" X" " ^" d" j" p" " v" |" " " " " (# # # $# (# T# D# L# T# \# d# l# # # %# +# 1# 7# =# C# Ѝ L# R# X# ^# d# ؍        H X m# s# y# # $ $ % $  $ |% 8$ D$ H$ H$ H$ H$ H$ H$ `$ `$ `$ `$ d$ l$ x$ |$ h% $ $ $ %$ +$ 1$ 7T% =$ C$ I$ O% U% [% a% g,% mL% sP% yT% d% h% x% |% % % | % % % ,& % % % & (& <& T<& L<& ( X <& L& L& |& p& \& h& p& x& & T& L& X ] b & & & ' & & & & & $& )& .& 4& :& @& F& L& R' ' \ \ X' ^,' d,' j4' p<' vD' |H' ' l' X' \' d' h' ' l' x' |' ' ' ' ' ' ' ' ' D( ' %' ' +' ' 7' =' ( L' R( ^( m( "0( s( (8( y,( 8( <( @( CL( L( `( `( .( h( t( t( 4( |( :( ( ( ( ( ( ( ( ( ( ( d( ( ( ( ( %( +( 1( ( =( C) ) I) U) [) ) a) @X) F) g) m) s) N) y) ) ) ) V )  ) $) ,) 8) H) P) `) T`) L`) `) p) t) x) ) ) T) L) \\ ) ) ) ) ) ) )  * ) ) $) ) * .* 4* :* @* (* e\ F(* L@* R@* XD* ^P* d`* jl* pp* vt* |* * l* * * * * d* * * * T* L* q\ z\ \ * * * * * * + $+ )0+ XȎ ]̎ bЎ gԎ .4+ 4D+ :D+ @H+ + T+ FT+ LX+ R\+ 1+ X`+ ^`+ dd+ jh+ p+ v+ |+ C+ l؎ q v  { + + ", + + + + (, + + + ,  ,  , d$,    < h p  $, @, @, %P, 7, +X, , h. :l, 7l, - =, L, R, ^, m, s, , y, , , ., , , , - - 4-  - 4- D- `- h- l- t- t- t- - - - - - - - - - - %- +- 1- =- C-  . I. U. [ . a<. gL. mX. sd. yd. .  ԏ ܏   . . . . (/ . . p0 @. . X0 . . / $/ ,/ (/ ,/ 8/ h/ X/ `/ h/ / x/ / / / / / / / "/ / )/ 0/ 70 =/ D/ K0 R0 Y`0 _00 f80 mP0 t`0 {l0 l0 0  \     ( , 0 \ ` x         ̐ Ԑ ܐ       < @ H T  ȑ ؑ % + 1  7  =4 C8 I@ O` Uh [| a0 h0 o0 v0 }3 1 (1 L1 d1 |1 1 1 1 1 1 2 2 02 D2 \2 t2 2 2  2  2  2  3  3 # 3 * 03 1 <3 8 p3 ? 3 F 3 M 3 T D5 Z 3 a 4 g 4 m 3 F4 t 4 { 4 4 04 04 N04 04 H4 4 x4 4 4 4 4 4 4 4 <5 4 4 5 4  5 $5  <5  D5  8 % R + d5 2 06 9 P7 ? H6 F 6 M 6 T 6 [ 6 b 7 i 87 p P7 w \7 ~ p7 7 7 7 7 7 X8 7 8 7 7 8 8 8 8 8 p8 X8 ; h8  8 8  8  8  9 % 8 , 9 3 9 : `: @ 9 G P9 M 89 T h9 Z P9 a d9 h @: n 9 t 9 { 9 9 9 9 9 : 9 9 : @: `: : x: : : ; : : : T;  :  ;  ;  D>  h; " x; ) ; 0 ; 7 ; = < C ; J < Q 4< W D< ] 4< d D< k < q < w < ~ < < = = pE = lC > 0> h> x> > > > A > > > > ?  ? ?  ?  $?  ? $ 8? + |? 2 ? 8 ? ? ? F @ L ? S ? Z @ ` d@ f @ m `@ t A z d@ x@ @ @ @ @ A $A 4A LA TA A A A A pB A B A $B A  B $B B EB LB SB ZB a4C gB nHE tC { C (C 8C PC lC R C D C C C C D ,D [ E[ L[ S[ Z[ a[ j[ q[ x[ ~[ [ ԓ   [ [ d\ [ [ ,\ \ \ (\ ,\ 0\ H\ `\ |\  $ H    & , 3@ :|\ A\ H\ O\ V\ ]\ d\ k\ r_ x] ] (] @] T] h] |] ] ] ] ] ] ] ]  ^  ^ ,^ ^ t^ |^ ^ ^ ^ ^ ^ %^ ,^ 3^ :^ C^ J^ Q^ X_ __ f_ m_ t<_ {<_ <_ L_ h_ _ p_ _ _ _ _ _ _ _ _ `` _ ` ` `` f l` ` ` d ` '` -` 4c :` Aa G` Na Ua \8a c`a ja ppa wa ~b a a b b b b b b b b b b f Ehi Kf Rf Yf `j fg mg tg {j Hg g \g g g g g h g g g g  h h h (h  h (h Lh  h  `h  h  i  h # h * i 0 h 7 di > i E k K i R i X i _ i f i m i t i z j i j j j ,j dj Dj `j dj xj j j j j j j j j j !j !8k !(l !8k !k #!l )!(l 0!n 6!m =!m C!Hm J!Xm Q!dm W!dm ^!m d!m k!m r!m x!m !m !m !n !m !n !n !n !(n !0n !`n !@n !Dn !Ln !Pn !\n !`n !ln !pn !tn "n "n "n "n "n %"n ,"n 3"n :"n D"L K"nx T"n ["o b"ho h"8o o"To v"do }"to "d " "ĕ " " " " "0 "H "` "| " " "Ė " " " #0 #L #\ #t # &# -# 4# ;#̗ B#ԗ I# P# W# ^#4 e#L l#h s# z# #̘ # #  #$ #< #T #` #d #t # # # # #Й # # # # #  $ $0 $\ $h "$p )$x 0$| 7$ >$ E$ L$ S$ Z$ a$ h$ o$ v$ }$$ $0 $` $t $| $ $ $ $ $ $ $ $ț $ԛ $ $ $( $4 $< %@ %L %t % % %% ,% 3% :% A% H% O%Ȝ V%Ԝ ]% d% k%  r% y%, %8 %to %o %o %o %r %dp %p %)Tx E)\x L)hx S)lx Z)|x a)x g)x n)x u)x |)x )x )x )x )x ) )y )y )y )y ),y )9 D9 L9 T9 \9 d9 l9 t9 z9p 9 9L 9P 9\ 9x 9p 9t 9| 9 9ĝ 9 9| 9 9 9 9 9؛ : :ț :ț : #: +: 3:, 9: A: I: O:( W:4 _: e:@ m:X u:l }: : : : : : :Ԝ : :̜ :Ԝ : : : : : : : : ; ; ;( ;X #;, +;4 3;@ ;;X C;\ I;d Q;p Y; a; i; q; y;ȝ ;Н ;ԝ ; ; ; ; ;  ; ;P ;  ;H ;0 ;0 ;4 ;H ;P ;X <d <\ <d <p <x '< /<̞ 5< =< E< M< U<̞ ]<ܞ e< m< u<  }<4 <@ <P <X < <\ <\ <\ <\ <\ <\ <\ <\ <\ <\ <t <| = = = = = '= /= 5=ܟ == E= M= U= ]=0 c= k=( s=0 {=P =< =d =P =p =x =| =| = =l = =Ġ =̠ =Р = =ؠ = > > > >$ ">  (>  0>< 6> >>p D> L>  T>$ \>, d>D j>D r>` z>p > >| > > > > >ȡ >С >ء > > >< >  >8 >Т >d > ?d ? ? ?Ȣ ? $?Ģ ,?Ȣ 4?̢ @4 F@8 N@p X@p `@ h@ p@\ v@ ~@T @ @ @ @ @L @ @ܤ @ @ @̤ @Ф @ؤ @$ @ܤ @  @ @ A A A A A (A  0A 8A$ @A, HA4 PA< XAD `AL hAT pAX xAd Ad Ap Ap A A A A A A Aإ A A Aȥ Aإ A A A B B B B  B 'B( /B, 7B4 ?B4 GB@ OB@ WBH _BP eB` mBx sB| yBx B| B B B B B B B B BĦ B BĦ B BЦ B B B B C C CL C  'CD -C 5C ;C CC( KC0 SC4 [CD cCH kCT uC< |Ct C| CT Cp Ct C| C C C C Ch C C C Cԧ C C C D  D4 D8 DȨ $D@ ,DL 4D\ I EIx LIx TI \I dI lI tIԮ {I IȮ IԮ Iخ I I I I I IX I( I( I@ IX Ih I I J T L X ] b g؟ lП q̟ vğ {        | t l d \ T L D c T L  X4h ]Dh     J<     $  ) .  4, :8 P bhh gh lh qh vh {h h h i  i   E L S Z g t S {   ( , L m L ` ` h l %p p               :" ' .$ 5( <0 C4 J< Q@ ^H eL lT sX z` d h p t x m m m m |     D    k'      # * ' 1 8 K  E L Y  `$ m0 t4 {4 @ 7T n T l p      %K   '               + +K$ n 2$ 98 @@ nT D GD N` Uh 5Kp ;Kl \l c| j X a  q ~  AK       GK0             ( , MK8 $n 8 $D WK` +P 8\ ?\ 8d ,n Pn Xn `n %hn +pn 1xn 7n =n Cn In On Un [n Fd M Z a h o  v    ]K\ ` cK    iK  5x oK x          uK     - 4 {K8 ; B  I V c  j( q, x8 < H  P X \ h l x K i p   H7 w ~     i7    K 7       7       ' . ;  B , I P ]( d, k4 r< yD L T \ d l t | K K    K <       < - : K K A H K( O ]$ K jL xX  K           ' 9  n n n n n o o   2, 9, @4  ND UH Kl \\ c` ql  x x     K      \            ( 8 < KX $P 1T 8T E\ R` Kx dl Yx f z s  K   K     h         K<  \D  K  K  < # *0 <0 10 =0 K0 D0 80 ?8 F< MD GP TP <P aP KP hP LP oP v` L` ` L` <` ,G` ` h l x    L L  'L  .L  5L    E L SL =@ o @o `o o o o o p !p ' p -  L< K  R( Y, f4 m8 L@ L0 c\q t@ P P \ d L |  B T L Xhq ]tq bq gq lq qq vq {q q q    L0  ]J     $$ )D .d 4| : @ F L R X ^ d j p v |  , d r d | l        $ $ D 0 @ J D t %X +p 7t = L R ^  m s y        T L X(r ]4r   8 , , 0 0 4 @ T@ L@ @ T T T T T T l $l l )l bJ . 4  X8r : @ L F L  R X ^ d l j p C ] E L T L X`t ]Xt bPt g@t l,t q t vt {t t s s s s s v v v v v pv dv Xv Lv 8v ,v  v v v u u u u u u |u lu \u Tu Du  3" }" | E L S Z 0 g H7 t {  i7   SH 0 8 @ H P X d t g |           % ' . x 5 < C J Q ^( e, 7< | l< sL zL P \ h Nt t O(, | OT8                +K( #( *8 18 8@ EH LL YP `T mh Oh tl O| {x       %O  +O  %K  a   n      9 1O p A   $ ( , P  K> 3"? JB ZB B %B +B 1C =C .$C C$C I8C XP8C QJI J(F _P(F fPG WJJ mP8J U8J [XJ alJ gJ mJ NJ sJ tPJ NHQ NM {PM PlN { lQ PQ yQ Q Q Q Q Q PQ NQ Q Q PQ Q *'Q Q T'Q 7Q Q Q PR R 8'R Y R  R  R {' R  R ' R  R ' R ' R ) R  R M'DR DR M1DR  R T \R :\R \R z1\R \R P\R \R P\R A2\R {\R \R 3R R R MR R TR LR X@| ]D| bL| R R R S R R R R R $R )R .R R 4R :R bJ S @R F S LS ,S g`| lh| R,S X@S ^@S S MS dTS jhS pS vS |S S S S S S S S S S ql| vp| {x| S T (T 0T XT 8T dT PT XT dT J|T 1T %|T +T JT 7T =T LT CU RU ^U mU s U y$U 0U TU 8U DU PU U TU `U hU tU U U OU U U U U U U U U U U U U dU U U %U +U 1U =V CV IV U,V [4V apc Etc Lc Sc Zc gc Jc tc {c c c MKc c c c c c c (} c c W 8d d  d 0d 4d =@d @d Xd k d xd d d d N@d 0} 8} P} d 'd .d 5d <d Cd Jd Qd Z Pz E\z KJz Lxz Sz Zz z gz tz {z z z z IMz z z z z z z { { {  { ,{ D{ X{ d{ p{ N{ |{ { J{ { { { '{ .{ 5{ <{ C{ J{ Q{ ^{ | T| L| X ] b g l q v {          | <| @| bJp} `| x| | | $| )| D} .| 4| :| @} F} L } R4} X<} ^D} dP} jX} ph} vl} } 4 D T x   Ȁ ؀  |} } } } J  ~ 8~ <~ D~ L~ P~ \~ |~ ~ ~ ~ %~  +~ 7~ =~   L R M\ ^8 m@ sH yX \ d t l |              8   8 P ` d h  %l + 1 =      ( C I U  [( a@ gL ml s y   Jԁ   ā ́ ԁ ԁ ԁ ԁ     X     $ , 8 @ H L ` ( l " ) 0 = D K R _Ԃ f؂ m؂ t {  a C0    ā ؁   h0 oP vT p t    ԃ    4D  $ , < D ` h   MȄ       Ȅ  ܄ #  *  J 1  8  ?  F  M ( Z , m 0 t 4 @ X ` h l dȅ    0 D t ȅ   N  < H h        P  Ȇ + Ԇ NԆ 2 ܆ ?  F  J$ M  T  [ $ b , i D p X w h  ~ p   ̇   ć ̇ ؇ ܇ (  ( D D H !JL       Ĉ %  ,  3  @  M  L Z ( a 8 t D P `  h h t     M   EJ    @ ԉ ܉        F  "  M  )  0   N C  J ( T ] D d L w T ~ \ d p x     Ȋ Ԋ    -J 7        $ $ + , 8 D ? H LH | T| L| T| L| T| L| T| L| T| L| T| L| T| L| T| L| T| L| T| L| T| L| T| L| T| L| T| L| T| L| LNċ ԋ Tԋ PH"P(P Q$o QpQ ,Q}D FQ b XQ+| ]Q  lQH  |Q Q Q@Q) Q' Qx Q, Q|Q "Q( "QdL Q| Q R $R$,p .R<&P 7R o ?R| FR m <MR|X WR4 hR8yR Rx) R{ R  RB R\ R Rc R R| R RHR\  S<S8 'Sk DSt*D MSXL"RShdSx$mS@ S S4+t Sy S"S( S"S|` ST Sy S`) Sx< TD T  'T3T:T6 @Tܪ QT l eTlT" sT  TH T`bX T ( TT( TT"T U U0"%U( 6U FUt"MU: TUm ZUH nUL }U| U U 4 U  UL"U(U 1 U UX Ujx V0} !V8 "V'x 'VD :V CVHlZVX "aVh "hVh qV zVg V| Vx"V@dh VD V Vpc\ V Vd WpW| +W* 8W< GW\c UW?s _W@P sW"W "WW l W W W`W` W"W0o Wh W4| W| W X XT +X7X0 DX PKX#, \XD oXy |X "X0} XX   Xl X@ X(L"Xl XXl X X@3 YbP Y "YԽ +Y8"1Yx$ LYܣ TY XYH `Y hYDc sYX4zYh "Y @YxY(YlY` PY< Y Y "Y. Y& Y Z(o  Z Z P&Z 1Z 5ZUp HZ [Z  jZ qZ4} wZH }ZH Z# ZXp Z\H\F ZZ,tT Z Z M ZS Z"["[\m [C [a( [ 5[ "=[ L[((W[8_[   e[Hx[b< [ [X[h"[dL [x"[@T [t [ [H \\ \h&\ "-\  ;\0 Y\P4 n\"s\ z\! \8m0 \\ \x 4 \D \c \\"4 \,\"\|= \ ]@"]to) ] (] P5]("B]\ M]8"S]| _]Hf]R k]Xs]y ] ]8} ] F ]p ]h"]xL]\ ]8} !]]@  ] ]< ]Px ^` P ^` %^[ 7^\ <^D$ P^ Z^ i^,S w^$ ^8^S  ^^<^X^| ^y ^l ^^<H ^ < ^"^ _L _d _D ,_L( :_4D_$ K_, Z_ b_l3q u__) _ _h[P _ _ _*@ _vx _*( _@` _L  _0 `( "`< `d .`8>`  L`y Z`l m`|\ z`H"`W  `0<" `| `X4`hX`z `8T ` `(*L a#$ ay ach .ax(7aR Eal Pal Zaz iadsa aT$ aJ a("aa8  aȅ` a$ az atc< a2 b0 b #b@ 1b\=b@3 Bb` Qb Xb fbX H sbA {bP b I bH  bXb`b%t b| b by b4 ccl <c c8b( 2cS ?cQ l Mcp dc8, qcDV c\ c"c` 8 c<@ c4P c c PcU chp d\ !dP 4d :d(dFd8"Ld(T ld[  }d d dH"dy d L1L21L31$$lit_1abi-note.Sabi-tag.h/usr/include/asm/unistd.hL11.Ltext0.Letextgcc2_compiled.__do_global_ctors_aux.L6.L2.L5.L3__CTOR_END__init_dummyforce_to_data__DTOR_END__p.2__DTOR_LIST____do_global_dtors_aux.L4fini_dummy__CTOR_LIST__tick_bitscross_bitsuparrow_bitsdownarrow_bitsphone_bitsphone1_bitsphone2_bitsphone3_bitsphone4_bitsmail_bitseye_bitsaudio_bitswb_bitstext_bitsunknown_bitsclock_bitswww_bitsucl_bitstools_bitsbullet0_bitsbullet1_bitsbroadcast_bitsmeeting_bitstest_bitssecure_bitssbroadcast_bitssmeeting_bitsstest_bitssdr_bits.LC0.LC1.LC2.LC3.LC4.LC5.LC6.LC7.LC8.LC9.LC10.LC11.LC12.LC13.LC14.LC15.LC16.LC17.LC18.LC19.LC20.LC21.LC22.LC23.LC24.LC25.LC26.LC27.LC28.LM1.LM2.L32.LM3.LM4.LM5.LM6.LM7.LM8.LM9.LM10.LM11.LM12.LM13.LM14.LM15.LM16.LM17.LM18.LM19.LM20.LM21.LM22.LM23.LM24.LM25.LM26.LM27.LM28.LM29.LM30.LM31.Lscope0buf.66.L92.L88.L103.Ltext1.Ltext2.L98.L102.L99.L100.LM32.LM33.LM34.LM35.LM36.Lscope1.LM37.LM38.LM39.L106.LM40.LM41.Lscope2.LM42.LM43.L109.LM44.Lscope3.LM45.LM46.LM47.LM48.LM49.LM50.L124.LM51.LM52.L113.LM53.LM54.LM55.Ltext3.LM56.LM57.LM58.LM59.LM60.LM61.Ltext4.LM62.LM63.LM64.LM65.LM66.L117.LM67.LM68.LM69.LM70.LM71.LM72.L118.LM73.LM74.LM75.L119.LM76.LM77.LM78.LM79.LM80.LM81.LM82.LM83.LM84.LM85.LM86.LM87.Lscope4.LM88.LM89.LM90.L127.LM91.LM92.LM93.LM94.LM95.Lscope5msg.2.L94first_addrlast_addr.L97.L116.L114.L105.L108.L115.L111.L128.L120.L122.L147.Ltext5.Ltext6.L144randseedseeded.L96first_adlast_adno_of_ads.L125.L140.L139.L129.L133.L134.L136.L143.L145.L160.L159.L150.L151.LM96.LM97.LM98.L152.LM99.LM100.LM101.LM102.LM103.LM104.LM105.LM106.LM107.LM108.L156.LM109.LM110.LM111.LM112.L157.LM113.LM114.LM115.LM116.LM117.LM118debugbuf.84.LC29.LC30.LC31.LC32.LC33.LC34.LC35.LC36.LC37.LC38.LC39.LC40.LC41.LC42.LC43.LC44.LC45.LC46.LC47.LC48.LC49.LC50.LC51.LC52.LC53.LC54.LC55.LC56.LC57.LC58.LC59.LC60.LC61.LC62.LM119.LM120.LM121.LM122.L304.LM123.LM124.LM125.LM126.LM127.LM128.LM129.LM130.LM131.LM132.LM133.LM134.LM135.LM136.LM137.LM138.LM139.LM140.LM141.LM142.LM143.LM144.L163.LM145.LM146.LM147.LM148.LM149.LM150.LM151.L165.LM152.L306.L166.LM153.LM154.LBB11.LM155.LM156.LBE11.LM157.LM158.L168.LM159.LM160.LM161.LM162.L170.LM163.LM164.LM165.L288.LM166.LM167.L172.LM168.LM169.LM170.LM171.LM172.L308.L173.LM173.LM174.L174.LM175.LM176.LM177.LM178.LM179.LM180.LM181.LM182.LM183.LM184.LM185.L175.LM186.LM187.LM188.L177.LM189.L178.LM190.LM191.LM192.L179.LM193.LM194.LM195.L289.LM196.L310.LM197.LM198.L181.LM199.LM200.L182.LM201.LM202.LM203.L183.LM204.L290.LM205.L186.LM206.LM207.L185.L291.LM208.L190.LM209.LM210.LM211.LM212.L292.LM213.LM214.LM215.LM216.LM217.L198.LM218.LM219.LM220.L199.LM221.L293.LM222.L202.LM223.LM224.L201.L313.LM225.LM226.LM227.LM228.L209.L208.LM229.LM230.L211.L210.LM231.LM232.L213.L212.LM233.LM234.LM235.LM236.L215.L214.LM237.L216.LM238.LM239.L312.LM240.LM241.L217.LM242.L315.L297.LM243.L303.LM244.LM245.LM246.LM247.LM248.LM249.L218.LM250.LM251.L219.LM252.LM253.L220.LM254.LM255.L222.L221.LM256.LM257.L294.LM258.LM259.L224.LM260.LM261.LM262.LM263.LM264.LM265.LM266.LM267.L228.L227.LM268.LM269.L229.LM270.L317.LM271.L230.LM272.LM273.LM274.LM275.LM276.LM277.LM278.LM279.L233.LM280.LM281.LM282.LM283.LM284.L295.LM285.L319.LM286.LM287.LM288.LM289.LM290.LM291.L286.LM292.L236.LM293.LM294.LM295.LM296.LM297.LM298.LM299.LM300.LM301.LM302.LM303.LM304.LM305.LM306.L296.LM307.LM308.LM309.LM310.LM311.LM312.LM313.LM314.LM315.L321.LM316.LM317.LM318.LM319.LM320.LM321.LM322.LM323.LM324.L242.LM325.LM326.L243.LM327.LM328.LM329.L244.LM330.LM331.L245.LM332.L246.LM333.LM334.L247.LM335.LM336.LM337.LM338.LM339.LM340.LM341.LM342.L248.LM343.LM344.L249.LM345.LM346.L250.LM347.LM348.LM349.L323.LM350.L252.LM351.LM352.LM353.LM354.LM355.LM356.LM357.LM358.LM359.L253.LM360.LM361.LM362.LM363.LM364.L254.LM365.LM366.L255.LM367.LM368.L257.LM369.LM370.LM371.LM372.LM373.LM374.LM375.LM376.LM377.LM378.LM379.L258.LM380.LM381.LM382.L278.LM383.L260.LM384.LM385.L261.L262.LM386.LM387.L298.LM388.L325.LM389.L266.LM390.LM391.LM392.LM393.L268.LM394.LM395.L299.LM396.LM397.L270.LM398.LM399.LM400.LM401.L272.LM402.LM403.LM404.LM405.LM406.L274.L273.LM407.LM408.LM409.LM410.L276.LM411.LM412.LM413.LM414.LM415.LM416.LM417.LM418.LM419.L327.LM420.LM421.LM422.LM423.LM424.LM425.L281.LM426.L282.LM427.LM428.LM429.LM430.LM431.L300.LM432.L329.LM433.LM434.LM435.LM436.LM437.LM438.LM439.LM440.LM441.LM442.LM443.LM444.LBE10.Lscope6.LC63.LC64.LC65.LC66.LC67.LC68.LC69.LC70.LC71.LC72.LC73.LC74.LC75.LC76.LC77.LC78.LC79.LC80.LC81.LC82.LC83.LC84.LC85.LC86.LC87.LC88.LC89.LM445.LM446.LM447.LM448.L418.LM449.LM450.LM451.LM452.LM453.LM454.L332.LM455.LM456.LM457.LM458.L333.LM459.LM460.L413.LM461.LM462.L335.LM463.LM464.L334.LM465.LM466.LM467.LM468.L339.LM469.LM470.LM471.LM472.L368.LM473.LM474.LM475.LM476.LM477.L344.LM478.LM479.LM480.L348.L351.LM481.LM482.L354.L357.LM483.LM484.LM485.LM486.L358.LM487.LM488.L359.LM489.LM490.LM491.L360.LM492.LBB16.LM493.L364.LM494.L363.LM495.LM496.LM497.LM498.LBE16.LM499.L420.LM500.LBE15.LM501.LBE14.LM502.Ltext7.LM503.LBB17.LM504.LBB18.LM505.LM506.LBE18.LBE17.Ltext8.LM507.L371.LM508.LM509.Ltext9.LM510.LBB19.LM511.LBB20.LM512.LBE20.LBE19.Ltext10.LM513.LM514.LM515.LBB21.LM516.LM517.LM518.LM519.LBE21.LM520.LM521.LM522.LM523.LM524.LM525.LM526.L377.L379.LM527.LM528.LM529.LM530.LM531.LM532.LM533.LM534.LM535.LM536.LM537.LM538.LM539.LM540.LM541.LM542.L386.LM543.L414.LM544.LM545.L388.LM546.L415.LM547.LM548.L390.LM549.L416.LM550.L422.LM551.LM552.LM553.LM554.LM555.LM556.LM557.LM558.LM559.LM560.L394.L396.LM561.LM562.LM563.LM564.LM565.LM566.LM567.L417.LM568.L402.L403.LM569.LM570.LM571.LM572.LM573.LM574.LM575.LM576.LM577.L405.LM578.LM579.LM580.LM581.L407.LM582.LM583.LM584.LM585.L408.L410.L409.LM586.L411.LM587.LM588.LM589.LM590.LM591.LM592.LM593.LM594.LM595.LM596.LBE12.Lscope7done.89.LM597.LM598.LM599.L427.LM600.LM601.LM602.LM603.LM604.LBE22.Lscope8.LM605.LM606.L430.LM607.Lscope9.LC90.LC91.LC92.LM608.LM609.L438.LM610.LM611.L434.LM612.L437.LM613.LM614.LM615.LM616.LM617.Lscope10.LC93.LC94.LC95.LC96.LC97.LC98.LC99.LC100.LC101.LM618.LM619.LM620.LM621.LM622.LM623.LM624.LM625.L525.LM626.LM627.LM628.LM629.LM630.LM631.LM632.LM633.LM634.LM635.LM636.LM637.LM638.LM639.LM640.LM641.LM642.L441.LM643.LM644.LM645.L442.LM646.LM647.LM648.LM649.LM650.LM651.Ltext11.LM652.LM653.LM654.LM655.LM656.LM657.LM658.LM659.Ltext12.LM660.LM661.LM662.L450.LM663.LM664.LM665.LM666.L452.LM667.LM668.LM669.LM670.L454.LM671.LM672.LM673.LM674.L456.LM675.LM676.LM677.L457.LM678.L458.LM679.L527.LM680.L459.LM681.LM682.LM683.LM684.LM685.L460.LM686.LM687.L461.LM688.LM689.L462.LM690.LM691.LM692.LM693.L464.LM694.LM695.LM696.LM697.L465.LM698.LM699.LM700.LM701.LM702.L466.LM703.LM704.LM705.LM706.LM707.L467.LM708.LM709.L469.LM710.LM711.L471.L529.LM712.L473.LM713.LM714.LM715.LM716.LM717.L474.LM718.LM719.LM720.LM721.L476.LM722.LM723.LM724.LM725.LM726.LM727.LM728.LM729.LM730.L477.LM731.LM732.LM733.LM734.LM735.LM736.L481.LM737.LM738.LM739.LM740.L531.LM741.LM742.LM743.L482.LM744.LM745.LM746.L503.LM747.L484.LM748.LM749.LM750.LM751.LM752.L522.LM753.LM754.LM755.LM756.L491.LM757.LM758.L486.LM759.LM760.LM761.L493.LM762.LM763.L523.LM764.LM765.L495.LM766.LM767.LM768.L533.LM769.L497.LM770.LM771.LM772.LM773.L499.L498.LM774.LM775.L500.LM776.LM777.L501.LM778.LM779.LM780.LM781.LM782.LM783.LM784.LM785.LM786.LM787.L504.LM788.LM789.LM790.L507.L506.LM791.LM792.L524.LM793.L535.LM794.L509.LM795.LM796.L511.LM797.L514.LM798.LM799.L513.LM800.LM801.LM802.L517.LM803.LM804.LM805.LM806.LM807.LM808.L519.LM809.LM810.LM811.LM812.LM813.LM814.LM815.LM816.LM817.LM818.LM819.LM820.LM821.LM822.LM823.LM824.LBE23.Lscope11.LC102set_time.LM825.LM826.L538.LM827.LM828.LM829.Lscope12namestr.100.LC103.LC104.LC105.LC106.LC107.LC108.LC109.LC110.LC111.LC112.LC113.LC114.LC115.LC116.LC117.LC118.LC119.LC120.LC121.LC122.LC123.LC124.LC125.LC126.LC127.LC128.LC129.LC130.LC131.LC132.LC133.LC134.LC135.LC136.LC137.LC138.LC139.LC140.LC141.LC142.LC143.LC144.LC145.LC146.LC147.LC148.LC149.LC150.LC151.LC152.LC153.LC154.LC155.LC156.LC157.LC158.LC159.LC160.LC161.LC162.LC163.LC164.LC165.LC166.LC167.LC168.LC169.LC170.LC171.LC172.LC173.LC174.LC175.LC176.LC177.LC178.LC179.LC180.LC181.LC182.LC183.LC184.LC185.LC186.LC187.LC188.LC189.LC190.LC191.LC192.LC193.LC194.LC195.LC196.LC197.LC198.LC199.LC200.LC201.LC202.LC203.LC204.LC205.LC206.LC207.LC208.LC209.LC210.LM830.LM831.LM832.LM833.L753.LM834.LM835.LM836.LM837.L544.LM838.LM839.LM840.L549.LM841.LM842.LM843.L551.LM844.LM845.LM846.L553.LM847.LM848.LM849.LM850.LM851.LM852.LM853.L755.L556.LM854.LM855.LM856.L557.LM857.LM858.LM859.L558.LM860.L559.L745.LM861.L663.LM862.LM863.LM864.LM865.L563.L561.LM866.LM867.L565.L564.LM868.L661.LM869.LM870.LM871.LM872.Ltext13.LM873.LBB30.LM874.LBB31.LM875.LM876.LBE31.LBE30.Ltext14.LM877.Ltext15.LM878.LBB32.LM879.LBB33.LM880.LM881.LBE33.LBE32.Ltext16.LM882.LM883.LM884.LM885.LM886.L757.LM887.L574.L575.LM888.LM889.L654.L642.L603.L600.L589.L580.L621.L636.L649.L586.L594.L615.L577.L609.L583.L653.LM890.LM891.L578.LM892.L626.LM893.LM894.LM895.L748.LM896.LM897.LM898.L740.LM899.LM900.L581.LM901.LM902.LM903.LM904.L749.LM905.LM906.LM907.L741.LM908.LM909.LM910.L584.LM911.LM912.LM913.LM914.LM915.LM916.LM917.LM918.LM919.L587.LM920.LM921.LM922.LM923.LM924.LM925.LM926.LM927.L738.LM928.LM929.LM930.L592.LM931.LM932.LM933.LM934.LM935.LM936.LM937.LM938.L576.LM939.L595.LM940.L759.LM941.LM942.L742.LM943.LM944.LM945.L598.LM946.L665.LM947.LM948.LM949.LM950.LM951.LM952.LM953.LM954.LM955.L601.LM956.LM957.LM958.LM959.L750.LM960.LM961.LM962.L743.LM963.L604.LM964.LM965.LM966.LM967.LM968.LM969.L607.LM970.LM971.LM972.LM973.LM974.LM975.LM976.LM977.L610.LM978.LM979.LM980.LM981.LM982.LM983.LM984.L613.LM985.LM986.LM987.L751.LM988.LM989.LM990.LM991.L616.LM992.L761.LM993.LM994.LM995.LM996.LM997.L619.LM998.LM999.LM1000.L752.LM1001.LM1002.LM1003.LM1004.L622.LM1005.LM1006.LM1007.LM1008.LM1009.LM1010.L625.LM1011.LM1012.LM1013.LM1014.LM1015.LM1016.LM1017.LM1018.LM1019.LM1020.L627.LM1021.LM1022.LM1023.LM1024.L630.LM1025.LM1026.LM1027.LM1028.LM1029.LM1030.LM1031.L633.LM1032.LM1033.LM1034.LM1035.LM1036.L744.LM1037.LM1038.LM1039.L637.LM1040.LM1041.LM1042.LM1043.LM1044.LM1045.L640.LM1046.L763.LM1047.LM1048.LM1049.LM1050.LM1051.LM1052.LM1053.LM1054.LM1055.LM1056.L643.LM1057.LM1058.LM1059.LM1060.LM1061.LM1062.LM1063.LM1064.LM1065.L645.LM1066.LM1067.LM1068.LM1069.LM1070.LM1071.LM1072.LM1073.LM1074.LM1075.L651.LM1076.LM1077.LM1078.LM1079.LM1080.LM1081.LM1082.LM1083.LM1084.LM1085.LM1086.LM1087.LM1088.LM1089.LM1090.L656.LM1091.LM1092.LM1093.LM1094.LM1095.LM1096.LM1097.LM1098.L660.LM1099.L765.LM1100.LM1101.LM1102.LM1103.L662.LM1104.LM1105.LM1106.LM1107.LM1108.L664.LM1109.LM1110.LM1111.LM1112.LM1113.LM1114.L666.LM1115.LM1116.LM1117.LM1118.LM1119.LM1120.LM1121.LM1122.LM1123.LM1124.LM1125.LM1126.LM1127.LM1128.LM1129.LM1130.LM1131.LM1132.L669.LM1133.LM1134.LM1135.LM1136.L671.LM1137.LM1138.LM1139.LM1140.L673.LM1141.LM1142.LM1143.LM1144.L675.LM1145.L768.LM1146.LM1147.L677.L679.LM1148.LBB34.LM1149.LM1150.LM1151.L680.LM1152.LBB35.LM1153.LM1154.LM1155.LM1156.LM1157.LM1158.LM1159.LM1160.LM1161.LM1162.LM1163.LM1164.LM1165.LM1166.L683.L685.LM1167.L767.LM1168.L770.LM1169.LM1170.LM1171.LM1172.LM1173.LBE35.L678.LM1174.L688.LM1175.LM1176.LM1177.LM1178.L773.LM1179.L690.LM1180.LM1181.LM1182.LM1183.LM1184.L692.LM1185.LM1186.LM1187.LM1188.LM1189.LM1190.LM1191.LM1192.LM1193.LM1194.LM1195.LM1196.LBE34.LM1197.LM1198.LM1199.LM1200.L695.LM1201.LM1202.LM1203.LM1204.LM1205.LM1206.LM1207.LM1208.LM1209.L772.LM1210.L775.LM1211.LM1212.LM1213.LM1214.LM1215.LM1216.LM1217.L700.LM1218.LM1219.LM1220.LM1221.LM1222.LM1223.LM1224.L701.LM1225.L702.LM1226.LM1227.LM1228.L746.LM1229.L778.LM1230.L705.L707.LM1231.LM1232.LM1233.LM1234.LM1235.L710.L712.LM1236.LM1237.LM1238.LM1239.LM1240.L715.L717.LM1241.LM1242.LM1243.LM1244.L719.LM1245.LM1246.LM1247.LM1248.LM1249.L721.L723.LM1250.L724.LM1251.LM1252.LM1253.LM1254.L777.L780.LM1255.LM1256.LM1257.LM1258.LM1259.LM1260.LM1261.LM1262.LM1263.LM1264.L726.LM1265.LM1266.LM1267.LM1268.LM1269.LM1270.LM1271.LM1272.LM1273.LM1274.LM1275.LM1276.LM1277.LM1278.L730.LM1279.LM1280.LM1281.L747.LM1282.L782.LM1283.LM1284.L722.LM1285.LM1286.LM1287.LM1288.LM1289.LM1290.LM1291.LM1292.LM1293.LM1294.L735.LM1295.LM1296.LM1297.LM1298.LM1299.LM1300.LM1301.LBE29.Lscope13.LM1302.LM1303.LM1304.LM1305.L785.LM1306.Ltext17.LM1307.LM1308.LM1309.Ltext18.LM1310.LM1311.LM1312.LM1313.LM1314.LM1315.LM1316.LM1317.L791.LM1318.Ltext19.LM1319.LM1320.LM1321.Ltext20.LM1322.LM1323.LC211.LC212.LC213.LC214.LM1324.LM1325.L802.L796.LM1326.L797.LM1327.L801.LM1328.LM1329.L798.LM1330.LM1331.LM1332.LM1333.LM1334.Lscope16.LM1335.LM1336.LM1337.LM1338.LM1339.LM1340.LM1341.L805.LM1342.LM1343.L809.LM1344.L807.LM1345.LM1346.LM1347.LM1348.LM1349.LM1350.L810.LM1351.LM1352.L812.LM1353.LM1354.LM1355.LM1356.LM1357.LM1358.L814.L813.LM1359.LM1360.LM1361.LM1362.L815.LM1363.LM1364.Lscope17.LC215.LC216.LC217.LM1365.LM1366.LM1367.LM1368.LM1369.L857.LM1370.LM1371.LM1372.LM1373.LM1374.LM1375.L822.LM1376.LM1377.L861.LM1378.LM1379.L824.LM1380.LM1381.LM1382.LM1383.LM1384.LM1385.LM1386.LM1387.LM1388.L825.LM1389.LM1390.LM1391.L832.LM1392.L828.L830.LM1393.LM1394.LM1395.LM1396.LM1397.LM1398.LM1399.L848.LM1400.LM1401.LM1402.LM1403.L836.LM1404.LM1405.LM1406.LM1407.LM1408.LM1409.LM1410.LM1411.LM1412.LM1413.LM1414.L837.LM1415.LM1416.LM1417.L838.LM1418.L840.L842.LM1419.LM1420.LM1421.LM1422.LM1423.L844.LM1424.LM1425.LM1426.LM1427.LM1428.L846.LM1429.LM1430.LM1431.LM1432.LM1433.LM1434.LM1435.LM1436.LM1437.LM1438.LM1439.LM1440.LM1441.L863.Ltext21.LM1442.LBB46.LM1443.LBB47.LM1444.LBE47.LBE46.Ltext22.LM1445.LM1446.LM1447.LM1448.LM1449.L851.LM1450.LM1451.LM1452.L852.LM1453.LM1454.LM1455.LM1456.LM1457.L853.LM1458.LM1459.LM1460.L854.LM1461.L860.LM1462.LM1463.LM1464.LM1465.LBE45.Lscope18no_of_ads.113.LM1466.LM1467.LM1468.LM1469.L866.LM1470.LM1471.LM1472.LM1473.LM1474.L867.L891.LM1475.L895.LM1476.L869.LM1477.LM1478.LM1479.LM1480.L871.LM1481.LM1482.LM1483.L874.LM1484.LM1485.LM1486.LM1487.LM1488.LM1489.LM1490.LM1491.LM1492.LM1493.L875.LM1494.LM1495.L876.L877.L892.LM1496.L879.LM1497.L881.LM1498.LM1499.LM1500.LM1501.LM1502.L883.LM1503.LM1504.LM1505.L884.L885.L893.LM1506.L887.LM1507.LM1508.LM1509.LM1510.LM1511.LM1512.LM1513.LM1514.LM1515.LM1516.LM1517.LM1518.L889.LM1519.LM1520.LM1521.LM1522.LM1523.L894.LM1524.LM1525.LM1526.LM1527.LM1528.LM1529.LM1530.Lscope19.LM1531.LM1532.LM1533.L913.LM1534.L899.L900.LM1535.LM1536.LM1537.L898.LM1538.L903.LM1539.L908.LM1540.LM1541.LM1542.L906.LM1543.L907.LM1544.LM1545.LM1546.LM1547.LM1548.LM1549.LM1550.LM1551.LM1552.LM1553.LM1554.LM1555.LM1556.LM1557.LM1558.LM1559.LM1560.Lscope20.LM1561.LM1562.LM1563.L926.L917.L919.LM1564.LM1565.LM1566.L922.L924.LM1567.LM1568.LM1569.LM1570.LBE50.Lscope21.LM1571.LM1572.LM1573.L929.LM1574.LM1575.LM1576.LM1577.LM1578.LM1579.LM1580.LM1581.L936.LM1582.L941.L938.LM1583.LM1584.LM1585.LC218.LM1586.LM1587.LM1588.LM1589.L944.LM1590.L949.L946.LM1591.L951.LM1592.LM1593.LM1594.LBE53.Lscope24.LM1595.LM1596.L961.LM1597.L954.LM1598.L955.LM1599.LM1600.LM1601.LM1602.LM1603.LM1604.Lscope25.LC219.LC220.LC221.LM1605.LM1606.LM1607.LM1608.LM1609.LM1610.L964.LM1611.L983.LM1612.LM1613.LM1614.LM1615.LM1616.LM1617.LM1618.LM1619.LM1620.LM1621.L966.LM1622.LM1623.LM1624.LM1625.LM1626.LM1627.LM1628.Ltext23.LM1629.LBB56.LM1630.LBB57.LM1631.LBE57.LBE56.Ltext24.LM1632.LM1633.LM1634.LM1635.LM1636.L970.LM1637.LM1638.LM1639.L971.LM1640.LM1641.LM1642.LM1643.LM1644.L972.LM1645.LM1646.LM1647.L973.LM1648.L977.LM1649.LM1650.LM1651.LM1652.LM1653.LM1654.LM1655.LM1656.LM1657.LM1658.LM1659.L981.LM1660.LM1661.LM1662.LBE55.Lscope26.LM1663.LM1664.L993.LM1665.L986.LM1666.L987.LM1667.LM1668.LM1669.LM1670.LM1671.LM1672.Lscope27.LC222.LM1673.LM1674.LM1675.LM1676.LM1677.LM1678.L996.LM1679.L1014.LM1680.LM1681.LM1682.LM1683.LM1684.L997.LM1685.LM1686.LM1687.L998.LM1688.LM1689.LM1690.LM1691.LM1692.LM1693.LM1694.Ltext25.LM1695.LM1696.LM1697.Ltext26.LM1698.LM1699.LM1700.LM1701.LM1702.LM1703.L1002.LM1704.LM1705.LM1706.LM1707.L1003.LM1708.LM1709.LM1710.L1004.LM1711.L1008.LM1712.LM1713.LM1714.LM1715.LM1716.LM1717.LM1718.LM1719.LM1720.LM1721.LM1722.LM1723.LM1724.LM1725.L1012.LM1726.LM1727.LM1728.Lscope28.LC223.LC224.LC225.LM1729.LM1730.LM1731.LM1732.L1017.LM1733.L1046.LM1734.L1047.LM1735.L1029.LM1736.LM1737.LM1738.L1019.L1021.LM1739.LM1740.LM1741.L1024.L1026.LM1742.LM1743.LM1744.LM1745.L1030.LM1746.L1032.L1033.LM1747.LM1748.LM1749.LM1750.LM1751.L1036.LM1752.LM1753.LM1754.LM1755.LM1756.LM1757.LM1758.LM1759.LM1760.L1041.L1043.LM1761.LM1762.LM1763.LM1764.LM1765.LBE62.Lscope29.L91.L112.L107.LBE3.L161.L153.L154.L155.L164.L169.LBE9.L192.L188.L187.L89.L90no_of_socks.70slist.71sockets.72.L104.L123.L110addr.75str.76.L176.L132.L148.L158.L126res.79.L189.L184.L200.L197.L205.L204.L203.L223.L240.L239.L234.LBB23.L251.L269.L279.Lscope14.L320.L302.L322.L324.Lscope15.L330.L392.L389.L337.L340.L342.L347.L350.L355.L391.L370.L372.L375.L376.L378.L380.L382.L398.L406.L453.L419.L423.L424.L429.LBB44.LBB45.LBE44.LBB48.LBB49.LBE49.LBE48.L445.Ltext27.LBB50.LBB51.LBB52.LBE52.LBE51.Ltext28.LBE43.L515.L512.L468.Ltext29.Ltext30.L478.L485.L488.L502.L530.L543.L536.Ltext31.Ltext32.L540.Lscope22.L547.L548.L552.Lscope23callid.120.L555.L93.LBE8.L135.L141.L162daynameslongdaynamesmonnameslongmonnamesemail.92.L194pids.101.L206.L207.LBE54synchronizefileNamenamedisplaygeometryargTable.L101.L95mainWindowcommand.L121.L167www_perror.L171.LBB8.LBB9.LBB10.LBE2cmd.24.L35.L33.L34empty_keybadpktlen_badpbit_decrypt.L10.L9des_keyinstall_key.L18.L16.L21.L29.L26.L38.L36PADDINGMD5_memcpyMD5Transform.L43.L40.L42Encode.L47MD5_memsetDecode.L54.L60keytable.L130.L137.L138.L142.L149.L191.L196.L225.L265getseedgoodkey.L275isgoodkey.L280.L283Base64.102.L311.L307.L318.L314.L316s_p0s_p1s_p2s_p3s_p4s_p5s_p6s_p7rolrordesKey.8desKeys.9oldKey.10keys.11oldWhat.12oldMode.13.L15.L23.L28.L31.L30.L41.LBB12.L46.L48.L50.L51.L52.LBB13.L56.LBB14.LBB15.LBE13.L61.L62.L64.L66.L68.L70.L77.L79.L86.LBB22.LBB24.LBB25.LBE25.LBE24.LBB26.LBB27.LBE27.LBE26.LBB28.LBB29.LBE28.LBB36.LBE36.L226.L232.L238.L256.L259.L267.LBE40.L131.L180longjmpstrcpysip_recv_tcpwebblocksTk_ParseArgvparse_sip_failcheck_x509_authenticationui_set_passphrasedumpui_getusernameget_pass_phrasenode6printfrandomdelete_addressload_crypted_fileui_getmonnameTcl_CreateFileHandlerrecvconnectgen_new_dataDecryptis_a_sip_requestui_sip_close_tcp_connectionsd_listenstrerrorwebdatado_climodvar__eprintfui_generate_portTcl_AddErrorInfousernameunlinksocket_DYNAMICcrypt_buffernode15doexitui_sip_parse_pathui_save_keysparse_sip_success__ctype_bnode3getenvno_of_tx_socks_etextsip_send_tcp_registergenerate_authentication_infosec_seedgets__strtol_internalTcl_Initsip_send_tcp_requestpassphrasehexdumpenctxt_fnamegetpidui_set_sipaliasfgetsget_advert_infoui_sip_send_tcp_replyx509bdy_fnamelinksocketui_getpidui_gethostaddrtcl_start_toolsres_mkquerymemcpyqfDESwrite_encryptionfind_keyname_by_keyperrornode11sip_finished_reading_tcpui_check_addressui_write_crypted_fileset_pass_phrasewrite_authenticationTcl_DeleteFileHandlergetuidsip_send_udp_registerqueue_ad_for_sendingfeofgenerate_addresssip_udp_rx_sockmallocnode13ui_fnui_generate_addresssip_tcp_accept_IO_2_1_stdin_ui_save_www_data_to_fileparse_sip_pathtcl_sipsleepTcl_DoOneEventtcl_pgp_cryptannounce_errornode5gen_new_cache_datasys_nerrrecvfromstore_addressparse_sip_progresshostaddrTcl_DeleteTimerHandlersocketselectinit_clihostnamegen_new_auth_datagenerate_x509_authentication_infofflushui_find_keyname_by_keywrite_crypted_fileToBase64helpdataintroTkCreateXEventSourceputenvui_sip_send_tcp_requestsec_longrandsip_tcp_listenui_delete_keymbone_faqsip_generate_callidstrncasecmpsendabortfind_key_by_nameMD5Finalui_initTk_MainWindowui_webtochmodwrkbuf_sip_tcp_freesip_close_tcp_connection_initsip_send_mcast_registerkeylistextract_field__sigsetjmpparse_sip_fatxsockis_a_bus_messageui_getemailaddresssapenc_fnameaccept_sys_nerrrenametcl_pkcs7_cryptui_create_interfacesip_send_tcp_reply_to_fdcallocsipdatalenlook_up_addresswebdatalennode9ui_write_encryptionbusrxsocksip_sendwritestore_encryption_in_memorytcl_sdpclifprintftcl_wwwui_add_keystrcatbindrfd2sock__umodsi3inet_addrTcl_CreateInterptx_sock_addrextract_ttlsip_send_udpsetsockoptsd_txgenerate_portui_getdaynamestoploadingsip_send_tcp_replyrxsock__res_sendguiadd_privacy_headerui_stop_session_adbin_to_b64_auxinterpstdinnode7ui_sip_send_udpparse_bus_message_starttcl_newstrstrgenerate_encryption_infosip_udp_tx_sockchangesparse_announcementsignalreadui_fn_namepluginsui_quitTk_GetNumMainWindowssendmsgTcl_GlobalEvalTcl_SetVarstrncmpnode8XSetIOErrorHandlerui_write_authenticationloggingstrncpystrcasecmpsend_sip_registerreallocui_sd_listennode10initnamesstore_x509_authentication_in_memorystrtokui_sip_parse_urlmemcmplistensdr_update_uigenerate_x509_encryption_infosip_parse_recvd_dataforksscanfbus_recvcheck_authenticationstrncatparse_sip_replyregister_keyui_lookup_hostui_make_random_keybus_sendsrand48freadnode14Tcl_GetVarstrdupparse_entryinit_bitmapsrx_sock_portgettimeofdayui_visiblefopen__bss_startmemsetmainTk_Initx509txt_fnamenode4_sys_errlisttcl_genericstop_session_adfcloseinet_ntoadebug1sys_errlisttimenode1delete_keymake_random_keyG_padCharsipaliasget_authentication_inforebuild_interfacehelpui_stop_www_loadingload_keyssip_get_methodaux_load_fileNull_Keystrcmpdata_startTk_GetUidlrand48getpwuidsip_request_readyx509sig_fnamesipdatagethostbyname_finitcl_cligethostnamesprintfMD5Initparse_sip_urlsip_readfrom_tcpcheck_addresssetlocalestderris_a_sip_replySet_Keytcl_parsed_pluginsTcl_CreateCommandsrandomMD5Updatexremove_interfacesip_registerenvremove_crcheck_encryptionseedrandsave_keystcl_cacheTkPlatformInitgetsockoptui_generate_idclean_up_and_dieTk_DefineBitmapparse_privhdrauthtxt_fnameparse_sip_redirectrecv_packetsfwriteui_createsessionload_cache_entry_edata__xstatTcl_CreateTimerHandler_GLOBAL_OFFSET_TABLE_extract_layers_endsec_randomkeybus_listenauthsig_fnameui_find_key_by_nameTcl_Evalinit_securityno_of_helpsipblockssx509txt_fnamedn_expanddebug_tcp_connsui_gethostnameplugtut__errno_locationexitmbone_toolscheck_x509_encryptionextract_partssx509enc_fnameui_load_keysnode12sip_get_dstnamesip_tcp_rx_sockforce_numericTcl_SetVar2bugssip_udp_listenfilenosip_tcp_connsget_sdr_hometcl_sdr_IO_stdin_usedtcl_pluginsdecrypt_announcement__libc_start_mainstrlenbus_send_new_appsend_advertrun_programx509key_fnameui_run_programstrchrmodnameexecvpui_get_passphrase__data_starttcl_sap_cryptwarn_tcl_special_charsis_a_sip_urlstore_data_to_announcettlfcntlencrypt_announcementtimed_send_advertsplat_tcl_special_charsEncryptrx_sock_addrbuild_packetstore_authentication_in_memoryno_of_rx_socksfind_end_of_headernode2Tcl_VarEvalclosestore_x509_encryption_in_memoryremove_interfacesip_recv_udpcheck_net_typefreeauthkey_fname__gmon_start__