⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protocol.tcl

📁 Linux下的MSN聊天程序源码
💻 TCL
📖 第 1 页 / 共 5 页
字号:
#	Microsoft Messenger Protocol Implementation#=======================================================================if { $initialize_amsn == 1 } {	global list_BLP list_cmdhnd sb_list contactlist_loaded	set contactlist_loaded 0	#To be deprecated and replaced with ::abook thing	set list_BLP -1	#Clear all user infomation	::abook::clearData	set list_cmdhnd [list]	set sb_list [list]	package require base64	package require sha1	package require snit	package require SOAP}namespace eval ::MSNFT {   namespace export inviteFT acceptFT rejectFT   #TODO: Instead of using a list, use many variables: ft_name, ft_sockid...   # If type is = 1 then it's an MSNP2P file send   proc invitationReceived { filename filesize cookie chatid fromlogin {type "0"}} {      variable filedata      if { $type == 0 } {      	set filedata($cookie) [list "$filename" $filesize $chatid $fromlogin "receivewait" "ipaddr"]      	after 300000 "::MSNFT::DeleteFT $cookie"       	SendMessageFIFO [list ::amsn::fileTransferRecv $filename $filesize $cookie $chatid $fromlogin] "::amsn::messages_stack($chatid)" "::amsn::messages_flushing($chatid)"      	#set filetoreceive [list "$filename" $filesize]      } elseif { $type == 1 } {      	set filedata($cookie) [list "$filename" $filesize $chatid $fromlogin]      }   }   proc acceptReceived {cookie chatid fromlogin message} {      variable filedata	  #status_log "DATA: $cookie $chatid $fromlogin $message $body\n"      if {![info exists filedata($cookie)]} {         return      }      #set requestdata [string range $requestdata 0 [expr {[string length requestdata] -2}]]      set requestdata [$message getField Request-Data]      status_log "Ok, so here we have cookie=$cookie, requestdata=$requestdata\n" red      if { $requestdata != "IP-Address:" } {      	status_log "Requested data is not IP-Address!!: $requestdata\n" red		return	  }      set ipaddr [$message getField $requestdata]      #If IP field is blank, and we are sender, Send the File and requested IP (SendFile)	if { ($ipaddr == "") && ([getTransferType $cookie]=="send") } {		status_log "Invitation to filetransfer $cookie accepted\n" black		SendMessageFIFO [list ::amsn::acceptedFT $chatid $fromlogin [getFilename $cookie]] "::amsn::messages_stack($chatid)" "::amsn::messages_flushing($chatid)"		set newcookie [::md5::md5 "$cookie$fromlogin"]		set filedata($newcookie) $filedata($cookie)		SendFile $newcookie $cookie		#TODO: Show accept or reject messages from other users? (If transferType=="receive")	} elseif {($ipaddr == "") && ([getTransferType $cookie]!="send")} {		SendMessageFIFO [list ::amsn::acceptedFT $chatid $fromlogin [getFilename $cookie]] "::amsn::messages_stack($chatid)" "::amsn::messages_flushing($chatid)"	#If message comes from sender, and we are receiver, connect	} elseif { ($fromlogin == [lindex $filedata($cookie) 3]) && ([getTransferType $cookie]=="receive")} {		after cancel "::MSNFT::timeoutedFT $cookie"		set port [$message getField Port]		set authcookie [$message getField AuthCookie]		#status_log "Body: $body\n"		ConnectMSNFTP $ipaddr $port $authcookie $cookie	}   }   proc getUsername { cookie } {      variable filedata      if {[info exists filedata($cookie)]} {         return [lindex $filedata($cookie) 3]      }      return ""   }   proc getFilename { cookie } {      variable filedata      if {[info exists filedata($cookie)]} {         return [lindex $filedata($cookie) 0]      }      return ""   }   proc getTransferType { cookie } {      variable filedata      if {[info exists filedata($cookie)]} {         return [lindex $filedata($cookie) 4]      }      return ""   }   proc cancelFT { cookie } {      variable filedata      if {[info exists filedata($cookie)]} {         ::amsn::FTProgress ca $cookie [lindex $filedata($cookie) 0]	 set sockid [lindex $filedata($cookie) 6]	 catch {puts $sockid "CCL\n"}         DeleteFT $cookie	 status_log "File transfer manually canceled\n"      }   }   proc timeoutedFT { cookie } {      variable filedata      after cancel "::MSNFT::timeoutedFT $cookie"      if {[info exists filedata($cookie)]} {         ::amsn::FTProgress e $cookie [lindex $filedata($cookie) 0]         DeleteFT $cookie	 status_log "File transfer timeouted\n"      }   }   proc FinishedFT { cookie } {      variable filedata      set filename [file join [::config::getKey receiveddir] [lindex $filedata($cookie) 0] ]      set finishedname [filenoext $filename]      if { [string range $filename [expr [string length $filename] - 11] [string length $filename]] == ".incomplete" } {            if { [catch { file rename $filename $finishedname } ] } {                  ::amsn::infoMsg [trans couldnotrename $filename] warning            }            }      DeleteFT $cookie      status_log "File transfer finished ok\n"   }   proc DeleteFT { cookie } {      variable filedata      if {[info exists filedata($cookie)] }  {         set sockid [lindex $filedata($cookie) 6]	 set fileid [lindex $filedata($cookie) 7]         status_log "Closing FT socket $sockid\n"         catch {fileevent $sockid writable ""}	 catch {fileevent $sockid readable ""}	 catch {close $sockid}         status_log "Closing FT file $fileid\n"	 catch {close $fileid}         unset filedata($cookie)      }   }   #################################   #All about receiving files   #################################   proc acceptFT {chatid cookie} {      #Send the acceptation for a file transfer, request IP      variable filedata      if { ![info exists filedata($cookie)]} {         return -1      }      after cancel "::MSNFT::DeleteFT $cookie"      set filedata($cookie) [lreplace $filedata($cookie) 4 4 "receive"]      set msg "MIME-Version: 1.0\r\nContent-Type: text/x-msmsgsinvite; charset=UTF-8\r\n\r\n"      set msg "${msg}Invitation-Command: ACCEPT\r\n"      set msg "${msg}Invitation-Cookie: $cookie\r\n"      set msg "${msg}Launch-Application: FALSE\r\n"      set msg "${msg}Request-Data: IP-Address:\r\n\r\n"      set msg [encoding convertto utf-8 $msg]      set msg_len [string length $msg]      set sbn [::MSN::SBFor $chatid]      if {$sbn == 0 } {         cancelFT $cookie         return 0      }      set sock [$sbn cget -sock]      ::MSN::WriteSBNoNL $sbn "MSG" "U $msg_len\r\n$msg"      after 20000 "::MSNFT::timeoutedFT $cookie"      ::amsn::FTProgress a $cookie [lindex $filedata($cookie) 0]      return 1   }   proc rejectFT {chatid cookie} {      set sbn [::MSN::SBFor $chatid]      if {$sbn == 0 } {         cancelFT $cookie         return 0      }      #Send the cancellation for a file transfer      set msg "MIME-Version: 1.0\r\nContent-Type: text/x-msmsgsinvite; charset=UTF-8\r\n\r\n"      set msg "${msg}Invitation-Command: CANCEL\r\n"      set msg "${msg}Invitation-Cookie: $cookie\r\n"      set msg "${msg}Cancel-Code: REJECT\r\n\r\n"      set msg [encoding convertto utf-8 $msg]      set msg_len [string length $msg]      ::MSN::WriteSBNoNL $sbn "MSG" "U $msg_len\r\n$msg"      status_log "Rejecting filetransfer sent\n" red      cancelFT $cookie   }   proc ConnectMSNFTP {ipaddr port authcookie cookie} {      #I connect to a remote host to retrieve the file      variable filedata      if {![info exists filedata($cookie)]} {        status_log "ConnectMSNFTP: Ignoring file transfer, filedata($cookie) doesn't exists, cancelled\n" red        return      }      status_log "Connecting to $ipaddr port $port\n"      ::amsn::FTProgress c $cookie [lindex $filedata($cookie) 0] $ipaddr $port      if { [catch {set sockid [socket -async $ipaddr $port]} res ]} {	set filename [lindex $filedata($cookie) 0]        cancelFT $cookie        ::amsn::FTProgress e $cookie $filename        return      }      lappend filedata($cookie) $sockid      #TODO: What are we cancelling here?      after cancel "::MSNFT::cancelFT $cookie"      fconfigure $sockid -blocking 0 -translation {binary binary} -buffering line      fileevent $sockid writable "::MSNFT::ConnectedMSNFTP $sockid $authcookie $cookie"   }   proc ConnectedMSNFTP {sockid authcookie cookie} {      variable filedata      if {![info exists filedata($cookie)]} {        status_log "ConnectedMSNFTP: Ignoring file transfer, filedata($cookie) doesn't exists, cancelled\n" red        return      }      set error_msg [fconfigure $sockid -error]      if {$error_msg != ""} {         status_log "Can't connect to server: $error_msg!!\n" white	 set filename [lindex $filedata($cookie) 0]	cancelFT $cookie	::amsn::FTProgress e $cookie $filename	return      }      fileevent $sockid writable ""      fileevent $sockid readable "::MSNFT::FTNegotiation $sockid $cookie 0 $authcookie"      status_log "Connected, going to give my identity\n"      ::amsn::FTProgress i $cookie [lindex $filedata($cookie) 0]      status_log "I SEND: VER MSNFTP\r\n"      catch {puts $sockid "VER MSNFTP\r"}   }   proc FTNegotiation { sockid cookie state {authcookie ""}} {      variable filedata      if {![info exists filedata($cookie)]} {        status_log "ConnectedMSNFTP: Ignoring file transfer, filedata($cookie) doesn't exists, cancelled\n" red        return      }      if { [eof $sockid] } {         status_log "FTNegotiation:: EOF\n" white	 set filename [lindex $filedata($cookie) 0]	 cancelFT $cookie	 ::amsn::FTProgress l $cookie $filename	 return      }      gets $sockid tmpdata      status_log "FTNegotiation: I RECEIVE: $tmpdata\n"      if { $tmpdata == "" } {         update idletasks         return      }      switch $state {      	0 {           if {[string range $tmpdata 0 9] == "VER MSNFTP"} {              catch {fileevent $sockid readable "::MSNFT::FTNegotiation $sockid $cookie 1"}              catch {puts $sockid "USR [::config::getKey login] $authcookie\r"}              status_log "FTNegotiation: I SEND: USR [::config::getKey login] $authcookie\r\n"	   } else {	      status_log "FT failed in state 0\n" red	      set filename [lindex $filedata($cookie) 0]	      cancelFT $cookie	      ::amsn::FTProgress l $cookie $filename	   }	}      	1 {           if {[string range $tmpdata 0 2] == "FIL"} {              set filesize [string range $tmpdata 4 [expr {[string length $tmpdata]-2}]]	      if { "$filesize" != "[lindex $filedata($cookie) 1]" } {	         status_log "Filesize is now $filesize and was [lindex $filedata($cookie) 1] before!!\n" white		 #cancelFT $cookie		 #return	      }              status_log "FTNegotiation: They send me file with size $filesize\n"              catch {puts $sockid "TFR\r"}              status_log "Receiving file...\n"              set filename [file join [::config::getKey receiveddir] [lindex $filedata($cookie) 0]]	      set origfile $filename              set num 1              while { [file exists $filename] } {                 set filename "[filenoext $origfile] $num[fileext $origfile]"                 incr num              }              if {[catch {open $filename w} fileid]} {                 # Cannot create this file. Abort.                 status_log "Could not saved the file '$filename' (write-protected target directory?)\n" red                 cancelFT $cookie                 ::amsn::FTProgress l $cookie $filename                 ::amsn::infoMsg [trans readonlymsgbox] warning                 return              }	      lappend filedata($cookie) $fileid              fconfigure $fileid -blocking 1 -buffering none -translation {binary binary}              #Receive the file              fconfigure $sockid -blocking 0 -translation {binary binary} -buffering full -buffersize 16384              catch {fileevent $sockid readable "::MSNFT::ReceivePacket $sockid $fileid $filesize $cookie"}	   } else {	      status_log "FT failed in state 1\n" red	      set filename [lindex $filedata($cookie) 0]	      cancelFT $cookie	      ::amsn::FTProgress l $cookie $filename	   }	}	default {	   status_log "FTNegotiation: Unknown state!!!\n" white	   cancelFT $cookie	}      }   }   proc ReceivePacket { sockid fileid filesize cookie} {      #Get a packet from the file transfer      variable filedata      if {![info exists filedata($cookie)]} {        status_log "ConnectedMSNFTP: Ignoring file transfer, filedata($cookie) doesn't exists, cancelled\n" red        return      }      if { [eof $sockid] } {         status_log "ReveivePacket EOF\n" white          set filename [lindex $filedata($cookie) 0]	  cancelFT $cookie	  ::amsn::FTProgress l $cookie $filename	 return      }     fileevent $sockid readable ""     set recvbytes [tell $fileid]     set packetrest [expr {2045 - ($recvbytes % 2045)}]      if {$packetrest == 2045} {         #Need a full packet, header included         ::amsn::FTProgress r $cookie [lindex $filedata($cookie) 0] $recvbytes $filesize         update idletasks         fconfigure $sockid -blocking 1         set header [read $sockid 3]         set packet1 1         binary scan $header ccc packet1 packet2 packet3         #If packet1 is 1 -- Transfer canceled by the other         if { ($packet1 != 0) } {            status_log "File transfer cancelled by remote with packet1=$packet1\n"            cancelFT $cookie	    return         }         #If you want to cancel, send "CCL\n"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -