<%@Language=VBScript debug="true" validateRequest="false"  %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Net" %>
<script runat="server" language=VBScript>
Dim sApp As String
Dim sSession As String
Dim sSesDiry As String

Dim sInid As String
Dim sExe As String
Dim sLib As String
Dim sDir As String
Dim sHtml As String

Dim sMeta As String
Dim sAjax As String
Dim sRelaunch As String = ""
Dim sMsg As String
Dim sLaunchIP As String
Dim nPort As Integer
Dim nTimeout As Integer
Dim sLaunchPswd As String
Dim sRmtRoot As String
Dim sCharSet As String = ""
Dim sCrypto As String = ""
Dim FIO_length As Integer
Dim FIO_offset As Integer

Sub Load_Session()
	Load_Variables()
	
	sSession = Request.QueryString("_session")
	if (sSession = "") Then sSession = Request.Form("_session")
	Trace.Write("Processing session " & sSession)

	Dim sVal As String
	if (Request.QueryString("dump") <> "") Then
		For each sVal in Application.Contents
			If Mid(sVal,1,1) <> "!" Then Response.Write(sVal & "=" & Application.Contents(sVal) & "<br>")
		Next
		Return
	End If
	
	if (sSession <> "") Then
		sSesDiry = Server.MapPath("tmp\" & sSession)
		Return
	End If
	
	Dim random As New Random()
	Dim sCurDir As String = ""
	Dim i As Integer
		
	Load_Inid()
	if sInid = "" Then Return
		
	Do
		sSession = ""
		for i = 1 to 12
			sSession = sSession & Chr(random.Next(97, 122))
		Next
		sSesDiry = Server.MapPath("tmp\" & sSession)
		if Directory.Exists(sSesDiry) = false Then Exit Do
	Loop
		
	Directory.CreateDirectory(sSesDiry)
	Dim fsSesInfo As New StreamWriter(sSesDiry & "\.info")
	
	fsSesInfo.WriteLine("HTTP_USER_AGENT=" & Request.ServerVariables("HTTP_USER_AGENT"))
	fsSesInfo.WriteLine("HTTP_HOST=" & Request.ServerVariables("HTTP_HOST"))
	fsSesInfo.WriteLine("REMOTE_ADDR=" & Request.ServerVariables("REMOTE_ADDR"))
	fsSesInfo.WriteLine("SERVER_ADDR=" & Request.ServerVariables("SERVER_NAME"))
	fsSesInfo.WriteLine("SERVER_PORT=" & Request.ServerVariables("SERVER_PORT"))
	fsSesInfo.WriteLine("SERVER_SECURE=" & Request.ServerVariables("SERVER_PORT_SECURE"))
	fsSesInfo.WriteLine("DOCUMENT_ROOT=" & sRmtRoot)
	fsSesInfo.WriteLine("WEB_URL=" & MID(Request.ServerVariables("PATH_INFO"),2) )
	fsSesInfo.WriteLine("INID=" & sInid)

	Dim Item as String
	fsSesInfo.WriteLine("")
	fsSesInfo.WriteLine("<Args count=" & Request.QueryString.Count & ">")
	For Each Item In Request.QueryString
	fsSesInfo.WriteLine(item & "=" & Request.QueryString(item) )
	Next
	fsSesInfo.WriteLine("</Args>")
	
	fsSesInfo.Close()
	
	If (sLaunchIP <> "") Then
		Spawn_ViaTcp()
		if (sSession = "") Then Return
	Else
		if (sDir <> "") Then
			sCurDir = Directory.GetCurrentDirectory()
			Directory.SetCurrentDirectory(sDir)
		End If
				
		System.Diagnostics.Process.Start(sExe,"*plus\inomads\inomads -arg '" & sSession & "=" & Server.MapPath("") & "'")
	
		Trace.Write("Spawning process...")

		if (sDir <> "") Then Directory.SetCurrentDirectory(sCurDir)
	End If
	
	For i = 1 to 200
		System.Threading.Thread.Sleep(50)
		if File.Exists(sSesDiry & "\.link") Then
			i = 1000
		End If
	Next
		
	Return
End Sub

Sub Spawn_ViaTcp()
	Dim tcpClient As New System.Net.Sockets.TcpClient()
	Try
		tcpClient.Connect(sLaunchIP, nPort)
	Catch
		Send_Error("Unable to connect to launch server on " & sLaunchIP & " port " & nPort.ToString())
		Return
	End Try

	Dim cClient As System.Net.Sockets.Socket = 	TcpClient.Client
	
	Dim sData as String
	
	sData = "????" & sLaunchPswd & Chr(0) & sSession & Chr(0) & sRmtRoot & Chr(0)
	
	Dim byData As [Byte]() = Encoding.ASCII.GetBytes(sData)
	
	ByData(0) = 222
	ByData(1) = 173
	ByData(2) = 190
	ByData(3) = 239
	
	Dim byHdr As [Byte]() = {0, 0}
	
	cClient.Send(byData)
	
	if Not(cClient.Poll(5*1000 * 1000, Sockets.SelectMode.SelectRead)) Then
		Send_Error("No Response from launch server")
		Return
	End If

	Dim bytes As Integer = cClient.Receive(byHdr)
	if (bytes <> 2) OR (byHdr(0) <> 79) OR (byHdr(1) <> 75) THEN
		Send_Error("Invalid Response from launch server")
		Return
	End If

	tcpClient.Close()

End Sub

Sub Exchg_Data()
	Dim sTcp As String

	if (sSession = "") Then Return

	sTcp = Application(sApp & "Lk_" & sSession)
	if sTcp = "" Then
		If Not(File.Exists(sSesDiry & "\.link")) Then 
			Send_Error("Unable to access " & sSesDiry & "\.link file to find server and port number")
			Return
		End If
		
		Dim rsLink As New StreamReader(sSesDiry & "\.link")
		sTcp = rsLink.ReadLine()
		rsLink.Close()
		
		Application(sApp & "Lk_" & sSession) = sTcp & ";;Exp:>" & DateTime.Now.AddMinutes(30).ToString("yyMMddHHmm")
	End If
	
	Dim sSplit() As String = Split(sTcp, ";")
	Dim tcpClient As New System.Net.Sockets.TcpClient()
	
	if (sLaunchIP<>"") Then sSplit(0) = sLaunchIP
	
	Dim tryCnt As Integer = 0
	Dim tryOkay As Integer = 0
	Dim sErr As String
	
	While tryOkay = 0
		Try
			tcpClient.Connect(sSplit(0), Convert.ToInt32(sSplit(1))  )
			tryOkay = 1
		Catch e As Exception
			System.Threading.Thread.Sleep(100)
			tryCnt = tryCnt + 1
			if tryCnt > 10 Then
				tryOkay = -1
				sErr = e.Message
			End If
		End Try
	End While

	If tryOkay = -1 Then
		Send_Error("Unable to connect to session " & sSplit(0) & " port " & sSplit(1) & "<br>Reason: " & sErr)
		return	
	End If
	
	Dim sData As String
	Dim sVal As String
	Dim sKey As String
	Dim sSeq as String
	
	sVal = ""
	sData = ""
	sSeq = ""
	
	Dim i As Integer = 0
	While i < Request.QueryString.Count
		sKey = Request.QueryString.GetKey(i)
		if sKey <> "" Then
			sData = sData & "," & sKey & "$"
			sVal = sVal & Chr(0) & Request.QueryString(i)
			if sKey = "_seq" Then
				sSeq = Request.QueryString(i)
				if sSeq = "Rscu" Then
					sData = sData & ",_inid$"
					sVal = sVal & Chr(0) & Request.Cookies("inid").Value
				End If
			End If
		End If
		i = i+1
	End While

	
	if sSeq = "Ajax" Then
		i = Request.TotalBytes
		
		sData = sData & ",___enc" ' Encode will be done by PxPlus
		sVal = sVal & Chr(0) & "1"

		Dim bData As [Byte]() 	
		bData = Request.BinaryRead(i)

		Dim n As Integer
		Dim sChr As String
		Dim nState As Integer
		
		n = 0
		nState = 0
		While n < i
			sChr = CHR(bData(n))
			n = n+1
			
			if nState = 0 Then
				sData = sData & "," & sChr
				nState = 1
			ElseIf nState = 1 Then
				If sChr <> "=" Then
					sData = sData & sChr
				Else
					sData = sData & "$"
					sVal = sVal & Chr(0)
					nState = 2
				End If
			Else
				If sChr <> "&" Then
					sVal = sVal & sChr
				Else
					nState = 0
				End If
			End If
		End While
	Else
		i = 0
		While i < Request.Form.Count
			sKey = Request.Form.GetKey(i)
			if sKey <> "" Then
				sData = sData & "," & sKey & "$"
				sVal = sVal & CHR(0) & Request.Form(i)
			End If
			i = i+1
		End While
	End If
	
	if Request.Files IsNot Nothing Then
		i = 0
		Dim objFile As HttpPostedFile
		While i < Request.Files.Count
			objFile = Request.Files(i)
			if (objFile IsNot Nothing AND objFile.FileName <> "" AND objFile.ContentLength > 0) THEN
				objFile.SaveAs(sSesDiry & "\" & Request.QueryString("_upload"))
				sData = sData & ",upload..filename$"
				sVal = sVal & Chr(0) & objFile.FileName
			End If
			i = i + 1
		End While
	End If
	
	Trace.Write("Data variables = " & sData)
	Trace.Write("   values=" & Replace(sVal, Chr(0), "|"))
	
	sData = Chr(0) & Request.ServerVariables("REMOTE_ADDR") & chr(0) & sData & sVal
	
	sSeq = Request.QueryString("_seq")
	if (sSeq = "") Then sSeq = Request.Form("_seq")
	sSeq = Right("0000" & sSeq, 4)
	
	if Len(sData) > 9900 Then
		sData = "+" & Right("00000000" & Convert.ToString(Len(sData)), 8) & sSeq & sData
	Else
		sData = Right("0000" & Convert.ToString(Len(sData)), 4) & sSeq & sData
	End If

	Dim sExit As String = ""
	
	Response.ContentType = "text/html; " & sCharset
	Response.AddHeader("Expires","Sun, 17 Dec 1989 07:30:00 GMT")

	Dim cClient As System.Net.Sockets.Socket = 	TcpClient.Client
	
	Dim byData As [Byte]() = Encoding.ASCII.GetBytes(sData)
	Dim byHdr As [Byte]() = {0, 0}
	
	Dim nPending As Integer
	
	cClient.Send(byData)
	
	Dim bytes As Integer
	Dim nPoll As Integer
	
	if nTimeout <= 0 Then
		nPoll = -1
	Else
		if nTimeout < 2000 then
			nPoll = nTimeout * 1000000
		Else
			nPoll = 2000000000
		End If
	End If
	
	i = 0
	nPending = 0
	
    sErr = ""

	Try
	    Do
    		if Not(cClient.Poll(nPoll, Sockets.SelectMode.SelectRead)) Then
                sErr = "Poll returned FALSE with blocks processed=" & CStr(i)
				Trace.Write("Poll returned FALSE with i=" & CStr(i))
				i = 0 - i
	   			Exit Do
	   		End If

			if ((i > 500) OR (nPending < 0)) Then
                sErr = "overrun. Blocks processed=" & CStr(i) & " Data still pending=" & cStr(nPending)
				Trace.Write("Forced exit i=" & CStr(i) & " Pending=" & cStr(nPending))
				i =  -1
	   			Exit Do
	   		End If	

    		if nPending = 0 Then
				bytes = cClient.Receive(byHdr)
    			nPending = (byHdr(0) AND 127) * 256 + byHdr(1)
				Trace.Write("Header size=" & CStr(nPending))
			else
				Trace.Write("Pending read=" & CStr(nPending))
			End If

			byData = New [Byte](nPending - 1) {}

			bytes = cClient.Receive(byData)
			Trace.Write("Received " & CStr(bytes) & " of " & CStr(nPending))
					
			if (bytes > 90000) Then
				Response.Write("Invalid response size of :" + CStr(bytes))
				return
			End If
			
			if (i = 0) Then
				sData = System.Text.Encoding.ASCII.GetString(byData, 0, bytes)
				if (Mid(sData,1,5) = "exit:") then
					sExit = Mid(sData,6)
					Exit Do
				End If
			End If
				
			If bytes > 0 Then
				i = i + 1
				if (bytes <> byData.Length) Then ReDim Preserve byData(bytes - 1)
				Response.BinaryWrite(byData)
				nPending -= bytes
			End If
			
			if ((nPending = 0) AND (byHdr(0) < 128)) Then 
				Trace.Write("Last packet")
				Exit Do
			End If
		Loop 
		
	Catch e As Exception
		sErr = "fatal communication error:" & e.ToString()
		sExit = ""
		i = 0
	End Try		

	tcpClient.Close()

    if (sErr <> "") Then Send_Error("Session connection terminated due to <b>" & sErr & "</b>")

	if (i < 0) Then Send_Error("<h1>Block count has gone negative</h1>") ' Send_SysHtml("sys_no_ses.htm")
	if (i <> 0) Then Return

	sRelaunch = ""
	
	sSplit = Split(sExit & Chr(9), Chr(9))
	
	sAjax = sSplit(0)
	
	Dim sHtmlDir As String = sHtml

	if (sSplit(3) <> "") Then sRelaunch = sSplit(3)
	if (sSplit(2) <> "") Then sHtmlDir = sSplit(2)
	
	if (sSplit(1) <> "") Then
		sMsg = sSplit(1)

		if (sMsg.IndexOf(".") < 0) Then
			sMsg = ""
			Send_Html("sys_" & sSplit(1) & ".htm", sHtmlDir)
			Return
		End If

		sAjax = sAjax & Chr(13) & Chr(10) & "sUrl = '" & sMsg & "';"
		Send_Html("sys_xfer.htm", sHtmlDir)
		Return
	End If
	
	Send_Html("sys_endapp.htm", sHtmlDir)
	
	Return
End Sub

Sub Send_Error(sErr As String)
	sMsg = sErr
	Send_SysHtml("sys_error.htm")
	Return
End Sub

Sub Send_SysHtml(sHtmlFile As String)
	Send_Html(sHtmlFile, sHtml)
End Sub

Sub Send_Html(sHtmlFile As String, sHtmlDir As String)
	Application.Lock()
	Application.Contents.Remove(sApp & "Lk_" & sSession)	
	Cleanup()
	Application.Unlock()
	
	Dim sPath As String
	
	sPath = Server.MapPath(sHtmlDir & "\" & sHtmlFile)
	if Not(File.Exists(sPath)) Then sPath = Server.MapPath("\syshtml\" & sHtmlFile)
	if Not(File.Exists(sPath)) Then
		Response.Write("<html><body>System HTML file " & sHtml & " has not been found.</body></html>")
		sSession = ""
		Return
	End If

	Dim rsHtml As New StreamReader(sPath)
			
	Dim sRec As String
	
	Do
		sRec = rsHtml.ReadLine()
		if (sRec Is Nothing) Then Exit Do
		
		Select Case sRec
			Case "//Ajax"
				if sAjax IsNot Nothing Then Response.Write(sAjax)
			Case "//Meta"
				if sMeta IsNot Nothing Then Response.Write(sMeta)
			Case "//Msg"
				if sMsg IsNot Nothing Then Response.Write(sMsg)
			Case "//Launch"
				if (sRelaunch <> "") Then Response.Write(sRelaunch)				
			Case Else
				Response.Write(sRec)
		End Select
	Loop 
	rsHtml.Close()
	sSession = ""
	sRelaunch = ""
	
End Sub

Sub Cleanup()
	Dim sNow = DateTime.Now.ToString("yyMMddHHmm")
	if (sNow = Application(sApp & "LastCleaned")) Then Return

	Dim sSplit() As String 
	Dim sTcp as String
	
	Application(sApp & "LastCleaned") = sNow

	Dim sDrop(Application.Contents.Count)
	Dim nDrop As Integer = 0
	Dim sKey As String
	
	For each sKey in Application.Contents
		sTcp = Application(sKey)
		If (sTcp.IndexOf(";;Exp:>") > 0)  Then
			sSplit = Split(sTcp, ">")
			if (sSplit(1) < sNow) Then 
				nDrop = nDrop + 1
				sDrop(nDrop) = sKey
			End If
		End If
	Next

	While nDrop > 0
		Application.Contents.Remove(sDrop(nDrop))
		nDrop = nDrop - 1
	End While
	
End Sub

Sub Load_Inid()
	if (Request.Cookies("inid") Is Nothing) Then
		Send_SysHtml("sys_getnid.htm")
		Return
	End If
		
	sInid = Request.Cookies("inid").Value
	if sInid <> "undefined" Then
		Return
	End If

	Dim sInidPath As String
	Dim sLastInid As String
	
	sInidPath = Server.MapPath("lastinid.conf")
	
	If DIR(sInidPath)<>"" Then
		Dim rsInid As New StreamReader(sInidPath)
		sLastInid = rsInid.ReadLine()
		rsInid.Close()
	Else
		sLastInid = "0000000000"
	End If
	
	sInid = DateTime.Now.ToString("yyMMddHHmm")
	if sInid <= sLastInid Then sInid = Right("00" & Convert.ToString(Convert.ToInt64(sLastInid)+1), 10)

	Dim wsInid As New StreamWriter(sInidPath)
	wsInid.WriteLine(sInid)
	wsInid.Close()
	
	Response.Cookies("inid").Value = sInid

	'  -- No longer set expiry -- using session cookies
	' 	Response.Cookies("inid").Expires = DateTime.Now.AddYears(5)
	' 

	Return
End Sub

Sub Load_Variables()
	sApp = "Pxp." & Request.ServerVariables("SERVER_NAME") & ":" & Request.ServerVariables("SERVER_PORT") & ":"
	Application.Lock()
	
	if (Application(sApp & "LoadInfo") = "") Then Load_Config()

	sLaunchIP = Application(sApp & "LaunchIP")
	sLaunchPswd = Application("!" & sApp & "LaunchPswd")
	nPort = Convert.ToInt32("0" & Application(sApp & "Port"))
	nTimeout = Convert.ToInt32("0" & Application(sApp & "Timeout"))

	sDir = Application(sApp & "Dir")
	sExe = Application(sApp & "Exe")
	sLib = Application(sApp & "Lib")
	sHtml = Application(sApp & "Html")
	sCharSet = Application(sApp & "CharSet")
	sRmtRoot = Application(sApp & "RmtRoot")
	sCrypto = Application(sApp & "Crypto")
	Application.Unlock()
	
	' Minimum settings
	
	if (nPort = 0) Then nPort = 4093
	if (nTimeout = 0) Then nTimeout = 60 * 5

	If (sDir = "") Then sDir = Server.MapPath("")
	If (sExe = "") Then sExe = Mid(sDir, 1, InStr(sDir, "lib") - 1)
	If (sLib = "") Then sLib = sExe & "\lib"
	If (sHtml = "") Then sHtml = "/syshtml"
	if (sRmtRoot = "") Then sRmtRoot = Server.MapPath("")
	return
End Sub

Sub Load_config()
	Dim sPath As String =  Server.MapPath("inomads.conf")
	Dim fsStream As New FileStream(sPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
	Dim fsConf As New StreamReader(fsStream)
	Dim sRec As String
	Dim nRec As Integer
	Do
		sRec = fsConf.ReadLine()
		if (sRec Is Nothing) then Exit Do
		nRec = nRec + 1
		if (MID(sRec, 1, 10) = "DIRECTORY=") Then Application(sApp & "Dir") = MID(sRec,11)
		if (MID(sRec, 1, 12) = "PXPLUS_EXEC=") Then Application(sApp & "Exe") = MID(sRec,13)
		if (MID(sRec, 1, 11) = "PXPLUS_LIB=") Then Application(sApp & "Lib") = MID(sRec,12)
		if (MID(sRec, 1, 12) = "SYSHTML_DIR=") Then Application(sApp & "Html") = MID(sRec,13)
		if (MID(sRec, 1, 10) = "LAUNCH_IP=") Then Application(sApp & "LaunchIP") = MID(sRec,11)
		if (MID(sRec, 1, 12) = "LAUNCH_PORT=") Then Application(sApp & "Port") = MID(sRec,13)
		if (MID(sRec, 1, 12) = "LAUNCH_PSWD=") Then Application("!" & sApp & "LaunchPswd") = MID(sRec,13)
		if (MID(sRec, 1, 12) = "LAUNCH_ROOT=") Then Application(sApp & "RmtRoot") = MID(sRec,13)
		if (MID(sRec, 1, 14) = "CHARACTER_SET=") Then Application(sApp & "CharSet") = " charset=" & MID(sRec,15)
		if (MID(sRec, 1, 12) = "TCP_TIMEOUT=") Then Application(sApp & "Timeout") = MID(sRec,13)
		if (MID(sRec, 1, 12) = "CRYPTO_SEED=") Then Application(sApp & "Crypto") = MID(sRec,13)
	Loop 

	fsConf.Close()
	Application(sApp & "Loads") = Application(sApp & "Loads") + 1
	Application(sApp & "LoadInfo") = "Loaded " & nRec & " records from " & sPath & " at " & DateTime.Now.ToString() 
	Return
End Sub	

Sub Download_File()
	Dim sFileName AS String
	sFileName = Request.QueryString("_download")
	
	' Get the file information
	
	Dim objSrcInfo As System.IO.FileInfo
	objSrcInfo = New System.IO.FileInfo(sSesDiry & "\" & sFileName)
	
	' Make sure it exists
	
	If objSrcInfo.Exists Then
		if InStr(Request.ServerVariables("HTTP_USER_AGENT"), "MSIE")<>0 Then
			Response.Redirect("/tmp/" & sSession & "/" & sFileName)
		Else
			Response.ContentType = "application/octet-stream"
			Response.AddHeader("Content-Disposition", "attachment; filename=" & CHR(34) & sFileName & CHR(34) )
			Response.AddHeader("Content-Transfer-Encoding","binary")
			Response.AddHeader("Content-Length", objSrcInfo.Length.ToString)
			Response.AddHeader("Expires","Sun, 17 Dec 1989 07:30:00 GMT")
			Response.WriteFile(objSrcInfo.FullName)
		End If
		Response.Flush()
		Response.End()
	Else
		sMsg = "Unable to locate file " & sFileName & " for download."
		Send_SysHtml("sys_error.htm")
	End If		

	Return
End Sub

Sub FileIO
    Dim sTxid As String
    Dim sFnc As String
    Dim sPath As String
    Dim sHash As String
    Dim sSHA As String

	Load_Variables()
    Response.ContentType = "application/stream"
    sTxid = Request.QueryString("txid")
    sFnc =  Request.QueryString("fnc")
    sPath = Request.QueryString("path")

    If sFnc = "" Then
        FileIO_error("Missing function specification")
        Return
    End IF
    If (sPath.IndexOf("/..") > 0) OR (sPath.IndexOf("\..") > 0) Then
        FileIO_error("Invalid pathname (double dot)")
        Return
    End IF

    sHash = mid(sTxid,1,8) & sCrypto & sPath & sFnc
    sSHA = ComputeSHA1(sHash)
    sSHA = ComputeSHA1(sHash  & sSHA)
    if sSHA <> mid(sTxid,9,40) Then
        FileIO_error("Wrong hash. S/B=" & sSHA)
        Return
    End IF

    sPath = Server.MapPath(sPath)
    sFnc = UCase(sFnc)
    if sFnc = "PUT" Then
        FileIO_Put(sPath)
    ElseIf sFnc = "GET" Then
        FileIO_Get(sPath)
    ElseIf sFnc = "DEL" Then
        FileIO_Del(sPath)
    Else
        FileIO_error("Un-supported function")
    End IF
    Response.Flush()
	Response.End()
    Return
End Sub

Sub FileIO_Get(sPath as String)
    If Directory.Exists(sPath) Then
        FileIO_GetDir(sPath)
    ElseIf File.Exists(sPath) Then
        FileIO_GetFile(sPath)
    Else
        FileIO_error("Cannot access file on server")
        Return
    End If
End Sub

Sub FileIO_GetDir(sPath as String)
    Dim nameList() As String = Directory.GetFiles(sPath)
	Dim name As String
    Dim fi As FileInfo
    Dim dirList As String
    Dim fileType As String
	Dim dt1970 As new DateTime(1970,1,1)
	Dim secondsUTC As Integer

    dirList = ""
    For Each name In nameList
		fi = new FileInfo(name)
        If fi.Name <> "." And fi.Name <> ".." Then
            if Directory.Exists(sPath & "\" & fi.Name) Then
                fileType = "D"
            Else
                fileType = "F"
            End If
			secondsUTC = Int((fi.LastWriteTimeUTC - dt1970).TotalSeconds)
            dirList = dirList & fi.Name & CHR(9) & fileType & CHR(9) & CStr(fi.length) & CHR(9) & CStr(secondsUTC) & CHR(13) & CHR(10)
        End If
    Next
    Response.AddHeader("Etag", CHR(34) & ComputeSHA1(dirList) & CHR(34))
    Response.AddHeader("Content-Range", "bytes 0-" & CStr(LEN(dirList)-1) & "/" & CStr(LEN(dirList)))
    Response.Write(dirList)
	Trace.Write("--- Okay == Driectory sent " & Cstr(LEN(dirList)) & " bytes")
End Sub

Sub FileIO_GetFile(sPath as String)
    Dim fileSize As Integer
    Dim buffer() As Byte

	Dim fs As FileStream = File.OpenRead(sPath)
    Dim br As BinaryReader = new BinaryReader(fs)

    fileSize = fs.Length
    FIO_length = fileSize
    FIO_offset = 0

    FileIO_GetRange()

	if FIO_offset <> 0 Then fs.Seek(FIO_offset, SeekOrigin.Begin)

    buffer = br.ReadBytes(FIO_length)
	br.Close()
	fs.Close()

    Response.BinaryWrite(buffer)

    Response.AddHeader("Etag", CHR(34) & ComputeSHA1bytes(buffer) & CHR(34))
    Response.AddHeader("Content-Range", "bytes " & CStr(FIO_offset) & "-"+CStr(FIO_offset + FIO_length - 1) & "/" & CStr(fileSize))
	Trace.Write("--- Okay == File sent " & Cstr(FIO_length) & " bytes")
End Sub

Sub FileIO_Put(sPath as String)
    Dim received As Integer

    FIO_offset = FIO_length = 0
    received = Request.TotalBytes

    FileIO_GetRange()
    
    if Request.TotalBytes <> FIO_length Then
		FileIO_error("PUT length mismatch: Read=" & CStr(received) & " Expected=" & CStr(FIO_length))
		Return
    End If

	Dim bData() As byte 	
	bData = Request.BinaryRead(FIO_length)

	if Request.Headers("Etag") <> ComputeSHA1bytes(bData) Then 
		FileIO_error("SHA Received mismatch")
		Return
    End If

	if FIO_offset = 0 Then FileIO_AssureDir(sPath)

	Dim fs As FileStream = File.OpenWrite(sPath)
    Dim bw as BinaryWriter = new BinaryWriter(fs)
	
	if FIO_offset <> 0 Then bw.Seek(FIO_offset, SeekOrigin.Begin)
	bw.Write(bData)
	bw.Flush()
	bw.Close()

	FileIO_Okay("File updated: wrote " &  CStr(FIO_length) & " bytes")
End Sub

Sub FileIO_AssureDir(sPath as String)
    Dim sDir As String
    sDir = Path.GetDirectoryName(sPath)
    if Directory.Exists(sDir) Then Return
    FileIO_AssureDir(sDir)
    Directory.CreateDirectory(sDir)
End Sub

Sub FileIO_Del(sPath as String)
    If Directory.Exists(sPath) Then
        FileIO_DelDir(sPath)
        FileIO_Okay("Directory Removed")
    Else
        Try
			File.Delete(sPath)
		Catch 
		End Try
        FileIO_Okay("File Removed")
    End If
End Sub

Sub FileIO_DelDir(sPath as String)
    Dim nameList() As String = Directory.GetFiles(sPath)
	Dim name As String
    Dim fi As FileInfo
    Dim path As String
	Try
		For Each name In nameList
			fi = new FileInfo(name)
			If fi.Name <> "." And fi.Name <> ".." Then
				path = sPath & "\" & fi.Name
				if Directory.Exists(path) Then
					FileIO_DelDir(path)
				Else
					File.Delete(path)
				End IF
			End If
		Next
		Directory.Delete(sPath)
	Catch
	End Try
End Sub

Sub FileIO_Error(sMsg as String)
	Trace.Write("*** FAIL == " & sMsg)
	Response.Write("Fail" & CHR(13) & CHR(10) & sMsg & CHR(13) & CHR(10))
	return
End Sub

Sub FileIO_Okay(sMsg as String)
	Trace.Write("--- Okay == " & sMsg)
	Response.Write("Okay" & CHR(13) & CHR(10) & sMsg & CHR(13) & CHR(10))
	return
End Sub

Sub FileIO_GetRange()
    Dim start As Integer
    Dim last As Integer
    Dim sRange As String
    Dim c AS String
    Dim i As Integer
    
    sRange = Request.Headers("Content-Range")
    if sRange = "" Then Return

    start = last = 0

    For i=1 to len(sRange)
        c = MID(sRange, i, 1)
        If c = "/" Then Exit For
        If c = "-" Then
            start = last
            last = 0
        ElseIF (c >= "0") AND (c <= "9") Then
            last = last * 10 + cInt(c)
        End If
    Next i

    FIO_offset = start
    FIO_length = last - start + 1
    return 
End Sub

Function ComputeSHA1(strToHash as String)
    Dim bytesToHash() As Byte = System.Text.Encoding.ASCII.GetBytes(strToHash)
	Return ComputeSHA1Bytes(bytesToHash)
End Function

Function ComputeSHA1Bytes(bytesToHash() as Byte)
    Dim sha1Obj As New System.Security.Cryptography.SHA1CryptoServiceProvider
    Dim sSHA1 As String
	Dim bytesSSH() As Byte

    bytesSSH = sha1Obj.ComputeHash(bytesToHash)

    sSHA1 = ""
    For Each b As Byte In bytesSSH
        sSHA1 += Mid("0123456789ABCDEF", Int(b / 16) + 1, 1) + Mid("0123456789ABCDEF", (b Mod 16) + 1, 1)
    Next

	Return sSHA1

End Function

</script>
<% 
	If Len(Request.QueryString("txid")) = 48 Then
        FileIO()
    Else
        Load_Session()
	    If Request.QueryString("_download") IsNot Nothing Then
    		Download_File()
	    Else
		    Exchg_Data()
        End If
	End If
%>
