http://i2p2.de%|%I2P%|% [Zarutian]: An start of an http://www.i2p2.de/samv2.html%|%SAMv2%|% library for Tcl ====== # I, Zarutian, hereby put this code into the International public domain. package require Tcl 8.5 package provide i2p/sam2 0.1 namespace eval i2p {} namespace eval i2p::sam2 { variable defaults { bridge {host localhost port none} type stream stream {limit none}} variable session_counter 0 variable sessions proc new_session {params} { variable session_counter set i session[incr session_counter] variable defaults if {![dict exists $params type]} { dict set params type [dict get $defaults type] } if {![dict exists $params bridge]} { dict set params bridge [dict get $defaults bridge] } if {![dict exists $params bridge host]} { dict set params bridge host [dict get $defaults bridge host] } if {![dict exists $params bridge port]} { dict set params bridge port [dict get $defaults bridge port] } if {![dict exists $params stream]} { dict set params stream [dict get $defaults stream] } if {![dict exists $params condition_callback} { error "an condition_callback must be provided" } variable sessions dict set sessions $i condition_callback [dict get $params condition_callback] dict set sessions $i socket [set sock [socket -async [dict get $params bridge host] [dict get $params bridge port]]] fconfigure $sock -buffering none -translation binary -encoding binary -blocking no fileevent $sock readable [list i2p::sam2::raw_recive_stage1 $i] puts -nonewline $sock "HELLO VERSION MIN=2.0 MAX=2.0\n" flush $sock return $i } proc raw_recive_stage1 {session_id} { variable sessions set sock [dict get $sessions $session_id socket] if {[eof $sock]} { close $sock after 0 [list {*}[dict get $sessions $session_id condition_callback] bridge connection closed $session_id ] return } dict append sessions $session_id raw_buffer [set buffer [read $sock]] if {[string first $buffer "\n"] != -1} { if {![string equal [string range $buffer 0 12] "HELLO REPLY "]} { after 0 [list {*}[dict get $sessions $session_id conditional_callback] bridge connection noHelloReply $session_id] } set line [split $buffer "\n"] set done 0 foreach pair [split $line " "] { lassign [split $pair "="] key value if {[string equal $key "RESULT"} { incr done; set RESULT $value } if {[string equal $key "VERSION"} { incr done; set VERSION $value } } if {$done != 2} { after 0 [list {*}[dict get $sessions $session_id conditional_callback] bridge connection missingHelloReplyParams $session_id] return } if {[string equal $RESULT "NOVERSION]} { after 0 [list {*}[dict get $sessions $session_id conditional_callback] bridge connection noversion $session_id] return } if {![string equal $RESULT "OK"]} { after 0 [list {*}[dict get $sessions $session_id conditional_callback] bridge connection resultNotOk $session_id] return } if {![string equal $VERSION "2.0"]} { after 0 [list {*}[dict get $sessions $session_id conditional_callback] bridge connection versionNot2.0 $session_id] return } #--- puts -nonewline $sock "SESSION CREATE } } } ======