Просмотр исходного кода

interconnect script connects to ssh central

Paul Klumpp 12 лет назад
Родитель
Сommit
212094bff0
1 измененных файлов с 458 добавлено и 0 удалено
  1. 458 0
      cims_interconnect.tcl

+ 458 - 0
cims_interconnect.tcl

@@ -0,0 +1,458 @@
+# CIMS: Community IRC Messaging Service
+# CIMS formerly known as MNET (Message Network)
+# Multiple Network Interconnection Script
+# Copyright (C) 2004 Paul-Dieter Klumpp
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+namespace eval ::cims::interconnect {
+	variable layout
+	variable sshcommand {ssh}
+	variable host {stomp@b4r.org}
+	variable mnet_interconnect_version "ic!0.1"
+
+
+}
+
+
+
+proc ::cims::interconnect::connect {} {
+	variable sshcommand
+	variable host
+	variable pipe
+
+	set command $sshcommand
+  lappend command $host
+	putlog "command is $command"
+	if {[catch {
+		
+		if {![info exists pipe] || $pipe == ""} {
+			set pipe [open "|$command" r+]
+			fconfigure $pipe -translation binary -blocking 0 -buffering line
+		} else {
+			putlog "already connected here: $pipe"
+		}
+	} error]} {
+		set pipe ""
+		putlog "error $error"
+		#conect again in a time
+	}  else  {
+
+		# read from console input
+		::cims::interconnect::readloop
+
+		# check if connection is alive.. if not, reset it.
+		::cims::interconnect::pingloop
+
+	}
+}
+
+proc ::cims::interconnect::connect_from_bind {nick mask hand chan text} {
+	::cims::interconnect::connect
+}
+
+
+proc ::cims::interconnect::disconnect {} {
+	variable pipe
+
+	::cims::interconnect::send "PART"
+	close $pipe
+	set pipe ""
+}
+
+proc ::cims::interconnect::disconnect_from_bind {nick mask hand chan text} {
+	::cims::interconnect::disconnect
+}
+
+proc ::cims::interconnect::reconnect {} {
+	::cims::interconnect::disconnect
+	::cims::interconnect::connect
+}
+
+proc ::cims::interconnect::reconnect_from_bind {nick mask hand chan text} {
+	::cims::interconnect::reconnect
+}
+
+
+proc ::cims::interconnect::send {msg} {
+	variable pipe
+
+	if {$msg != "" && $pipe != ""} {
+		putlog "writing $msg to pipe '$pipe'"
+
+		if {[catch {
+			puts $pipe "$msg"
+		} error]} {
+			close $pipe
+			set pipe ""
+
+			# well, it seems, our connection is broken, let's reconnect in 2 seconds.
+			utimer 2 "::cims::interconnect::connect"
+		}
+	}
+
+}
+
+proc ::cims::interconnect::send_from_bind {nick mask hand chan text} {
+	::cims::interconnect::send "$text"
+}
+
+proc ::cims::timeout_reply_from_ic_for_netbot {bcid network freqname source nick} {
+  variable mnet_reached_users 
+	variable mnet_reached_userlist
+  variable mnet_reached_chans
+
+	# clean $name and $source
+	set freqname [::putils::kill_spaces $freqname]
+	set source [::putils::kill_spaces $source]
+	
+	# easify variables
+	set userlist $mnet_reached_userlist($freqname,$source)
+	set user_cnt [llength $userlist]
+	set mnet_reached_users($freqname,$source) $user_cnt
+
+	set chan_cnt $mnet_reached_chans($freqname,$source)
+
+	
+	# inzwischen drfte auch die antwort gekommen sein.. also jetzt mnet_reached_* auswerten nach timeout..
+	
+	# make stats channel-dependent 
+	#putlog "::cims:: * userlist is finally: $userlist "
+	putlog "::cims:: * After ALL: Count_Users: $user_cnt  Count_Channels: $mnet_reached_chans($freqname,$source)"
+	
+	# Give him a reply.
+	::cims::put_bot $rec_botnick "mnet_answer $network $freqname $source $users $count_channels $unique_userlist"
+	
+}
+
+proc ::cims::timeout_reply_from_local_for_ic {bcid network freqname source} {
+  variable mnet_reached_users 
+	variable mnet_reached_userlist
+  variable mnet_reached_chans
+
+	# clean $name and $source
+	set freqname [::putils::kill_spaces $freqname]
+	set source [::putils::kill_spaces $source]
+	
+	# easify variables
+	set userlist $mnet_reached_userlist($freqname,$source)
+	set user_cnt [llength $userlist]
+	set mnet_reached_users($freqname,$source) $user_cnt
+
+	set chan_cnt $mnet_reached_chans($freqname,$source)
+
+	
+	# inzwischen drfte auch die antwort gekommen sein.. also jetzt mnet_reached_* auswerten nach timeout..
+	
+	# make stats channel-dependent 
+	#putlog "::cims:: * userlist is finally: $userlist "
+	putlog "::cims:: * After ALL: Count_Users: $user_cnt  Count_Channels: $mnet_reached_chans($freqname,$source)"
+	
+	# Give me some reply.
+	::cims::interconnect::send "BC_RE $bcid Users=$user_cnt,Channels=$chan_cnt"
+}
+
+
+# this proc is a new proc for cims. 
+# the message came from interconnect and injects into the netbots and own channels
+proc ::cims::message_from_interconnect {network freqname source nick text} {
+  variable mnet_reached_users 
+  variable mnet_reached_userlist
+  variable mnet_reached_chans
+
+	#putlog "freqname: $freqname"
+	#putlog "source: $source"
+	#putlog "nick: $nick"
+	#putlog "text: $text"
+
+	# reset stats .. because he is just freshly sending
+	set mnet_reached_users($freqname,$source) "0"
+	set mnet_reached_userlist($freqname,$source) ""
+	set mnet_reached_chans($freqname,$source) "0"
+
+	::cims::history_queue $network,$freqname $nick $source $text
+	
+	# send them first, we await a reply!
+
+	# single sends TO ALL REMOTE BOTS with their remote CHANNELS...
+	# let's see which mode for sending is used...
+	::cims::message_to_netbots $network $freqname $source $nick $text
+	
+	# SEND TO ALL OWN CHANNELS...
+	# send to all own channels, except to the channel the message originating from:
+	::cims::message_to_own_channels $network $freqname $source $nick $text
+
+		
+}
+
+proc ::cims::interconnect::add_up {bcid item count} {
+	variable receive_count
+
+	# schon drin?
+	if {![info exists receive_count($bcid)]} {
+		set receive_count($bcid) ""
+	}
+
+	set position [lsearch $receive_count($bcid) $item]
+
+	if {$position > -1} {
+		#putlog "item: $item is drin, weil posi $position"
+		set the_old_count [lindex $receive_count($bcid) [expr $position + 1]]
+
+		# the_old_count gets increased by $count
+		incr the_old_count $count
+
+		# we set it ..
+		lset receive_count($bcid) [expr $position + 1] $the_old_count
+
+	} else {
+		#putlog "item: $item nicht drin, weil posi $position"
+		lappend receive_count($bcid) "$item" "$count"
+	}
+	
+	#putlog "hum: $receive_count($bcid)"
+}
+
+# called right before the output...
+proc ::cims::timeout_reply_from_local_for_netbots_plugin {freqname source} {
+	upvar output output
+	set bcid $::cims::interconnect::sources($freqname,$source)
+
+	set output "$output $::cims::interconnect::receive_count($bcid)"
+}
+
+# this is the stuff we read on the console.
+proc ::cims::interconnect::work {inputline} {
+	variable broadcasts
+	variable sources
+	variable receive_count
+
+	#putlog "work that out: $inputline"
+
+	regexp -lineanchor {^.*\d: (.*)} $inputline matched sub
+	putlog "subline: $sub"
+
+	if {[regexp -all {^PONG} $sub] > 0} {
+		#putlog "interconnect pong received"
+
+	} elseif {[regexp -lineanchor -all {^(BC_ID) (.+) for: (.+),(.+),(.+)$} $sub whole command bcid network freqname source] > 0} {
+	# this tells us, we sent a REQ_BC before. 
+
+		set broadcasts($bcid) [list "$network" "$freqname" "$source"]
+		set ::cims::interconnect::sources($freqname,$source) "$bcid"
+
+		#putlog "bcid vars saved: $broadcasts($bcid) "
+
+		# reset receive counters.
+		set receive_user_count($bcid) 0
+		set receive_item_count($bcid) 0
+
+	} elseif {[regexp -lineanchor -all {^(BC_RE) (.+) (.+)=(\d+),(.+)=(\d+)$} $sub whole command bcid user_string user_count item_string item_count] > 0} {
+		#BC_RE f4k3h4sh 5,3
+		# central does some routing over central to make sure, the BC_RE message is only sent to me
+		# ok cool .. i hope we sent a message with that $bcid before. And 
+
+		#.. we check on $bcid - find out the correct cims-vars (chan, freq, etc) 
+		# and add user_count, item_count to them. 
+		
+		# now, let's validate that bcid .. we check if that bcid exists.. so the originating message is from me.
+		if {[info exists broadcasts($bcid)] == 1} {
+			set that $broadcasts($bcid)
+			set network [join [lindex $that 0]]
+			set freqname [join [lindex $that 1]]
+			set source [join [lindex $that 2]]
+
+			# count up
+			::cims::interconnect::add_up "$bcid" "$user_string" "$user_count"
+			::cims::interconnect::add_up "$bcid" "$item_string" "$item_count"
+
+			# ready the variable, so it can be read from the plugin.
+			set ::cims::interconnect::receive_count($bcid) "$::cims::interconnect::receive_count($bcid)"
+
+		}
+	
+	} elseif {[regexp -lineanchor -all {^(BC) (.+) (.+),(.+),(.+),'(.+)','(.+)'$} $sub whole command bcid network freqname source nick text] > 0} {
+
+		# THIS IS FRESH INPUT. ESCAPE IT.
+		set freqname [split $freqname]
+		set source [split $source]
+		set nick [split $nick]
+		set text [split $text]
+		putlog "freqname: $freqname"
+		putlog "source: $source"
+		putlog "nick: $nick"
+		putlog "text: $text"
+
+
+		# parse here above.. or just use:
+		#set network "QDEV"
+		#set freqname "-dev-"
+		#set source "http://qwnu"
+		#set nick "testnickname"
+		#set text "testmessage"
+
+		# here, we read a message from central and put it to all local channels and netbots.
+		::cims::message_from_interconnect $network $freqname $source $nick $text
+
+
+		# in the meantime, we even get all replies and counts (by ::cims::). 
+		# Now, we should get that count and send it to the central as a reply. Hitting the original sender.
+		utimer 4 "::cims::timeout_reply_from_local_for_ic $bcid $network $freqname $source"
+		
+
+	} elseif {[regexp -all {^WHO.*} $sub whole] > 0} {
+		# ignore this one - it's fully handled by central.
+	} elseif {[regexp -all -nocase {^C (.*): (.*)} $sub whole sub1 sub2] > 0} {
+		# received, with command "C "
+		if {"$sub2" != ""} {
+			::putils::put_local_msg "#aztest" "C $sub1: $sub2"
+		}
+	} else {
+		# received, but it has no command
+		#::putils::put_local_msg "#aztest" "not handled: $sub"
+	}
+
+}
+ 
+proc ::cims::interconnect::read {} {
+	variable pipe
+
+	#putlog "into read"
+
+	if {$pipe != ""} {
+		#while { ![eof $pipe] } {
+			gets $pipe inputline
+			if {$inputline != ""} {
+				::cims::interconnect::work "$inputline"
+			}
+			
+		#}
+	}
+	#putlog "ending of read"
+}
+
+
+proc ::cims::interconnect::readloop {} {
+	variable pipe
+
+	# check timers.. if old is running, don't start a new one
+	set timerlist [utimers]
+
+	set matched 0
+	foreach {timerinfo} $timerlist {
+		set timer_proc [join [lindex $timerinfo 1]]
+		set timer_id [join [lindex $timerinfo 2]]
+		if {[string match -nocase "::cims::interconnect::readloop" $timer_proc] == 1} {
+			set matched 1
+		}
+	}
+
+	if {$matched == 0 && $pipe != ""} { 
+		utimer 1 "::cims::interconnect::readloop" 
+	}
+
+	# read a line
+	::cims::interconnect::read
+}
+
+proc ::cims::interconnect::ping {} {
+	#putlog "into read"
+
+	::cims::interconnect::send "PING"
+}
+
+proc ::cims::interconnect::pingloop {} {
+	variable pipe
+
+	# check timers.. if old is running, don't start a new one
+	set timerlist [utimers]
+
+	set matched 0
+	foreach {timerinfo} $timerlist {
+		set timer_proc [join [lindex $timerinfo 1]]
+		set timer_id [join [lindex $timerinfo 2]]
+		if {[string match -nocase "::cims::interconnect::pingloop" $timer_proc] == 1} {
+			set matched 1
+		}
+	}
+
+	if {$matched == 0 && $pipe != ""} { 
+		utimer 120 "::cims::interconnect::pingloop" 
+	}
+
+	# start a ping
+	::cims::interconnect::ping
+}
+
+# this proc is a plugin proc for cims. it only gets executed if it exists.
+# the message came from our bot.
+proc ::cims::message_from_local_plugin {network freqname source nick text} {
+
+	# send the message into central
+	putlog "wo bin ich da? $source"
+	::cims::interconnect::send "REQ_BC $network,$freqname,$source,'$nick','$text'"
+
+	# save BC_ID for this combination of parameters - is done in the above "::work"
+
+	# receive answers from the other networks
+
+	# prepare stats so that the local stats-counter takes it. the local stats are getting put out
+  # at the end of ::cims::messaging_public_from_bind by ::cims::reply_timeout
+
+
+}
+
+# this proc is a plugin proc for cims. it only gets executed if it exists.
+# we received a message from a netbot
+proc ::cims::message_from_netbot_to_plugin {netbot network freqname source nick text} {
+	# send the message into central
+	::cims::interconnect::send "REQ_BC $network,$freqname,$source,'$nick','$text'"
+
+	# receive answers from the other networks
+	# in the meantime, we get all the BC_RE replies and counts.
+	# Now, we should get that count and send it to originating netbot.
+	#utimer 4 "::cims::timeout_reply_from_ic_for_netbot $netbot $network $freqname $source $nick"
+
+	# send an own answer to the originating netbot
+
+}
+
+
+proc ::cims::interconnect::bindings {} {
+
+  bind pub - !mnet_connect    ::cims::interconnect::connect_from_bind
+	bind pub - !mnet_disconnect ::cims::interconnect::disconnect_from_bind
+	bind pub - !mnet_reconnect  ::cims::interconnect::reconnect_from_bind
+	bind pub - !mnet_input      ::cims::interconnect::send_from_bind
+
+}
+
+proc ::cims::interconnect::main {} {
+	variable mnet_interconnect_version
+  variable pipe
+
+  putlog "mnet! = mnet interconnection script loaded: $mnet_interconnect_version"
+
+	::cims::interconnect::bindings
+	::cims::interconnect::connect
+
+}
+
+
+namespace eval ::cims::interconnect {
+  # timer weil $botnet-nick nicht sofort von eggdrop gesetzt wird
+  utimer 3 "::cims::interconnect::main"
+}