$debug
--------------------------------------------------------------------------------
-- March 2000
-- Big big changes to the whole process. Well, at least to the beginning of 
-- the process. Before we start into installing the standard Touch 1 stuff
-- we need to decide what OS the current version is running on and, if it
-- is still DOS, we need to install (oh, be still my heart) Linux! Here is
-- an outline of what happens:
-- If there is a /proc/version file then
--    we are running Linux. Nothing else needs to be done.
-- else
--    copy three disks into the c:\ directory.
--    run esplink lint132
--    run unesp x single.esp
--    run bp.exe to figure out which partion is the boot partition
--    create a linux.bat file that will start linux
--    modify the config.sys and autoexec.bat files
--    clean up by deleting lint*.*, single.esp, esplink.com, unesp.exe, bp.exe
-- end
-- go on with the rest of the install.
--
-- When the Touch 1 reboots, Linux!
----------------------------------------------------------------------------------




-------------------------------------------------------- Intro     --------
-- With this release of the 1500V version of the Touch 1, there is one
-- file that depends on the version of the hardware. The file is:
-- * pchp.exe
-- We will ship the versions of the files that support the 1500V hardware
-- on disk 2 and the files that support the 1000V hardware on disk 3.

sourceDir = "a:\\"
--sourceDirBase = "n:\\home\\paul2\\t1_old\\3.21p\\upgdlin\\"
--ViewSourceDirBase = "n:\\\\home\\\\paul2\\\\t1_old\\\\3.21p\\\\upgdlin\\\\"
--sourceDirBase = "/DOS/"
--ViewSourceDirBase = "/DOS/"

--------------------------------------------------- RunningInLinux -----------
-- RunningInLinux reports the operating system running on the Touch 1. 

function RunningInLinux()
	local file, openErr;

	file,openErr = readfrom("/proc/version")

	if file == nil then -- We must be on DOS
		return nil
	else	
		readfrom()
		return 1
	end
end

----------------------------------------------- MakeLinuxBat ----------
-- MakeLinuxBat uses a dos utility called "part" to decide which 
-- partition we will be installing on. Then it creates the correct
-- linux.bat file in the C:\linux directory.
function MakeLinuxBat()
	execute("c:\\bp.exe")
	
	local res, openErr
	res, openErr = readfrom("c:\\part.txt")
	local partnum
	partnum = read("*l")
	readfrom()
	res, openErr = writeto("c:\\linux\\linux.bat")
	local runline
	runline = format("loadlin bzimage root=/dev/hda%d rw", tonumber(partnum)+1)
	write(runline)
	writeto()
end	

---------------------------------------------- CopyLinuxDisks ---------
function CopyLinuxDisks(installedDir)
-- MessageBox("Installing into " .. installedDir .. "\\")	-- ZONK ****
	-- We're running in DOS.
	setwidgittext("lint132.esp", 3)
	errText = copyfile(installedDir .. "lint132.esp", "c:\\lint132.esp", 5)
	setwidgittext("lint132.e01", 3)
	errText = copyfile(installedDir .. "lint132.e01", "c:\\lint132.e01", 5)
	setwidgittext("lint132.e02", 3)
	errText = copyfile(installedDir .. "lint132.e02", "c:\\lint132.e02", 5)
	setwidgittext("bp.exe", 3)
	errText = copyfile(installedDir .. "bp.exe", "c:\\bp.exe", 5)
	setwidgittext("unesp.exe", 3)
	errText = copyfile(installedDir .. "unesp.exe", "c:\\unesp.exe", 5)
	setwidgittext("esplink.com", 3)
	errText = copyfile(installedDir .. "esplink.com", "c:\\esplink.com", 5)
-- MessageBox("Done installing into " .. installedDir .. "\\")	-- ZONK ***
end	
---------------------------------------------- UnzipLinux -------------

function UnzipLinux()
	setwidgittext("Installing OS. This takes a long time.", 3)
	if readfrom("c:\\touch1\\#\\single.esp") ~= nil then
		readfrom()
		execute("del c:\\touch1\\#\\single.esp")
	end
	execute("c:\\esplink c:\\lint132 > esp.out")
	execute("c:\\dos\\move c:\\touch1\\#\\single.esp C:\\") 
	execute("c:\\unesp xy c:\\single C:\\ > esp.out")
	execute("del c:\\single.esp")
	execute("del c:\\lint*.*");
end

--------------------------------------------- CheckHardwareType -------
--
-- CheckHardwareType reports the type of hardware the software is being 
-- installed on. it returns 1000 for 1000v hardware and 1500 for 1500v
-- hardware. 

function CheckHardwareType(inLin)
	local openRes, openErr 	-- The results of trying to open the ver.txt file go here
	local hwType			-- The type of hardware we are looking at (1000 | 1500)
	local execError

	-- testrev.exe puts the result of the call in c:\touch1\inst.ver by default
	if inLin then
--		RemountDrive("A:")
--		execError = execute("/mnt/A/testrev")
--		openRes, openErr = readfrom("/DOS/touch1/inst.ver")
		-- If we're in Linux, we're using 1500V hardware.
		-- testrev doesn't support PCI hardware, so we can't use it yet.
		hwType = 1500
	else
		execError = execute(sourceDir .. "testrev")
		openRes, openErr = readfrom("c:\\touch1\\inst.ver")
		if openRes == nil  then
			MessageBox(openErr)
			return openRes, openErr
		else
			local typeText = read()
			hwType = tonumber(typeText)		 -- This forces a numeric conversion
		end
		readfrom()		-- Close the inst.ver file
	end 

	return hwType
end

------------------------------------------------------- InstallLinux ------
-- 
-- It installs Linux

function InstallLinux(installedDir)
	CopyLinuxDisks(installedDir)
	UnzipLinux()
	MakeLinuxBat()
	execute("ren c:\\config.sys c:\\config.dos");
end
-------------------------------------------------------- IsZipped ---------
-- This function returns a nil if a file is not zipped. Otherwise, it 
-- returns the name the file will have after it is unzipped. It will only
-- work properly with compressed .exe .sct or .hlt files.

function IsZipped(fileName)
	-- Assume that the file is not zipped
	local retVal = nil
	-- Grab the last two letters of the file name and convert them to uppercase
	local nameLen = strlen(fileName)
	local lastTwo = strsub(fileName, nameLen-1)
	lastTwo = strupper(lastTwo)
	
	-- If the last two letters were GZ then return a filename with the 
	-- the uncompressed file extension
	if lastTwo == "GZ" then
		local exttab = {EGZ="EXE", SGZ="SCT", HGZ="HLT"}
		local extension = strupper(strsub(fileName, nameLen-2))
		retVal = strsub(fileName,1,nameLen-3)
		retVal = retVal .. exttab[extension]
	end
	return retVal
end

----------------------------------------------------- CheckContentsFile ---
function CheckContentsFile(diskNum)
	local diskNumber, file, retVal
	retVal = nil
	-- Grab the disk number
	if isRunningLinux then
		RemountDrive("A:")
	end

if sourceDirBase ~= nil then -- ZONK ****
	sourceDir = sourceDirBase .. "disk" .. tonumber(diskNum) .. "\\"
--	MessageBox("Looking for dir: " .. ViewSourceDirBase .. "disk" .. tonumber(diskNum) .. "\\\\")
end
	file = readfrom(sourceDir .. "contents.lst")

	if file ~= nil then
		diskNumber = tonumber(read())
	else
		diskNumber = 0
	end
	
	if tonumber(diskNum) == diskNumber then
		retVal = 1
	end
	readfrom()	-- Close the contents file.
	return retVal
end

--------------------------------------------------- DoesFileExist -----------
function DoesFileExist(fileName)
	local retVal
	retVal = nil
	if isRunningLinux then
		RemountDrive("A:")
	end

	if readfrom(fileName) ~= nil then
		readfrom()
		retVal = 1
	end
	return retVal;
end

-------------------------------------------------------- AskForDisk -------
-- This function displays a screen that asks for a specific disk number.
-- It then waits for a button to be pressed. When the button is pressed, 
-- the function looks for the contents.lst file on the disk and reads
-- the first line. The first line of the contents.lst file is a single int
-- that is the disk number. The disk number is compared to the desired disk
-- number and if they are the same, the function returns a 1. Otherwise, 
-- the function asks for the disk again. If the use presses cancel from
-- the request screen, the function returns a nil. The screen number 180 
-- is the request screen. This cannot be moved or changed! Remember, the
-- screen is in the currently installed main.sct file, not the one being
-- installed

function RequireDisk(checkfn, desiredVal, desiredDisk)
	local diskNumber, selection, file, message


	-- While it is not the one we are looking for, keep asking until we
	-- get the one we want or the user presses cancel.
	while checkfn(desiredVal) == nil do
		pushscreen()
		openscreen(180)		-- This screen number (180) cannot change
		message = getwidgittext(2)	-- This widgit number cannot change
		setwidgittext(format(message, desiredDisk),2 )
		selection = getbuttonpress()
		openscreen(popscreen())
		if selection == 4 then	---- 4 is the CANCEL button
			return nil
		end
	end
    return 1
end

-------------------------------------------------------- Main Program -----

-- Conventions:
--   For errors, return a nonzero.  The C-side will pick this up as
--   an error, and state that the installation failed.
--     -90 = can't find one of the required disks, followed by disk #
--		 -91 = can't copy a file, followed by error text

-- Set up for some user feedback
copyingMessage = getwidgittext(3)
diskOfMessage = getwidgittext(4)
linuxIsInstalled = nil

isRunningLinux = RunningInLinux()

----- Directory Declarations ----
if isRunningLinux then
	-- This should not have a trailing slash for the delDir function
	tempDir = "/tmpinst"	
	-- This shold have the trailing slash
	finalDir = "/DOS/touch1/"
	execute("mkdir /tmpinst")

	-- The Touch 1 changes touch1.sh to run from the touchbak directory,
	-- and since we no longer cause damage to the touch1 directory, it's
	-- better to never switch out of it.
	writeto("/touch1.sh")
	write("#!/bin/sh\ncd /DOS/touch1\n./pchp\n")
	writeto()
	execute("chmod +x /touch1.sh") -- make sure it's executable

else
	-- This should not have a trailing backslash for the delDir function
	tempDir = "c:\\tmpinst"		
	-- This shold have the trailing backslash
	finalDir = "c:\\touch1\\"

	-- The Touch 1 changes touch1.bat to run from the touchbak directory,
	-- and since we no longer cause damage to the touch1 directory, it's
	-- better to never switch out of it.
	writeto("c:\\touch1.bat")
	write("cd \\touch1\r\npchp\r\n")
	writeto()

end

-- Check hardware after forcing that next reboot will be in touch1 dir.
HardwareVersion = CheckHardwareType(isRunningLinux)

if HardwareVersion ~= 1500 then
	return -91, "These installation disks\ndon't work for this\nhardware.\nGet different\ninstallation disks."
end

if readfrom("c:\\linux\\linux.bat")  ~= nil or isRunningLinux ~= nil then
	readfrom()
	linuxIsInstalled = 1
--	MessageBox("Linux is Installed")
end

-- Find the version of software currently installed on the tester


-- for now, we cannot check the hardware version, maybe later.
-- if SWVersion == nil then
--	local HWVersion = GetHardwareVersion()	
	-- The first version of the software that needs the new .exe is
	-- version 3. The first version of the hardware that needs the 
	-- new .exe is V2.0. Sooooo; we need to add a 1 to the hardware
	-- version to get the correct software to install.
--	SWVersion = HWVersion + 1	
--end

-- We need to start with disk 1
diskNumber = 1

if RequireDisk(CheckContentsFile, diskNumber, diskNumber) == nil then
	return -90, 1	-- can't find one of the required disks, disk 1
end

-- Find out how many disks are in this install
readfrom(sourceDir .. "contents.lst") -- We've opened the file OK once.  
				-- Don't need to check for errors since the file is cached.
tonumber(read()) -- skip over disk number
setwidgittext("Cleaning up old temp files", 3)
totalDisks = tonumber(read())

if isRunningLinux ~= nil then
--	MessageBox("Running Linux") -- ZONK ***
	destDir = tempDir .. "/"
else
	destDir = tempDir .. "\\"
--	setwidgittext("Cleaning up old linux files", 3)
-- Linux will be replaced.  No need to delete it.  In some cases can't clear it.
--	cleardirectory("c:\\linux") -- Update it if it was a partial install. ZONK *****
--	MessageBox("Not running Linux") -- ZONK ***
end

if isRunningLinux ~= nil then
	execute("mkdir " .. tempDir) -- Create it if it doesn't alredy exist
	execute("rm " .. tempDir .. "/*") -- manually remove all old files from directory
else
	cleardirectory(tempDir);
end

-- What OS are we running?  If it isn't Linux, we'll need to install it.
iNeedToInstallLinux = nil
-- if isRunningLinux == nil and HardwareVersion == 1500 and linuxIsInstalled == nil then
if isRunningLinux == nil and HardwareVersion == 1500 then
--	MessageBox("Will Install Linux") -- ZONK ***
	iNeedToInstallLinux = 1
else -- don't need to install Linux
	totalDisks = 2 -- won't use last 3 disks.  Will actually only use 2 disks.
end

-- This will be a list of files installed. We use it to build a new ver.txt
fileNumber = 1
filesInTemp = {}

if diskOfMessage ~= nil then
	setwidgittext(format(diskOfMessage, diskNumber, totalDisks), 4)
end

iMarkedExecutable = nil
errText = nil
repeat
	-- The contents.lst file contains the names of all the files that need to 
	-- be installed off of this disk. The following repeat loop reads each
	-- file name and copies the file so named from the install disk to the 
	-- Touch 1. When we hit the end fo the file, read() will return a nil
	-- The contents.lst file also contains the checksums of all the files that
	-- need to be copied.  The file "checksum" in Linux, or "checksum.exe"
	-- in DOS is included on the 1st disk.  Run it to make sure that all of the
	-- files are copied OK.
	local diskFileNumber = 0
	local diskFile = {}
	diskFile.name = {}
	diskFile.checksum = {}
	repeat
		fileNameLine = read()
		if fileNameLine ~= nil then
			local commaPos = strfind(fileNameLine, ",")
			if commaPos == nil then
				return -91, "contents.lst corrupt.\nGet new install disks."
			end
			fileName = strsub(fileNameLine, 1, commaPos - 1) -- first part of fileNameLine
			fileCheckSum = tonumber(strsub(fileNameLine, commaPos+1)) -- last part of fileNameLine
			if copyingMessage ~= nil then
				setwidgittext(format(copyingMessage, fileName), 3)
			end
			-- Copy the file from the floppy to the temp dir
			errText = copyfile(sourceDir .. fileName, destDir .. fileName, 5)
			if errText ~= nil then
				return -91, errText	-- -91 == copy file error, and some text
			end
			-- If the file is zipped, unzip it and change fileName to the unzipped file name
			--local realName = IsZipped(fileName)
			--if realName ~= nil then
			--	execute(tempDir .. "\\" .. "minigzip -d " .. tempDir .. "\\" ..fileName)
			--	fileName = realName	
			--end
			-- Add the file to the list of files that will go into ver.txt
			filesInTemp[fileNumber] = fileName
			fileNumber = fileNumber + 1
			diskFileNumber = diskFileNumber + 1
			diskFile.name[diskFileNumber] = fileName
			diskFile.checksum[diskFileNumber] = fileCheckSum
		end
	until fileNameLine == nil
	readfrom() 	-- Close the contents.lst file.

	local iIndex = 1
--	MessageBox("Will Now check Checksums") -- ZONK ***
	while iIndex <= diskFileNumber do
		-- Check all the file checksums, now that we have the checksum program in the temp dir.
		if isRunningLinux then -- can't scribble on same file more than once
			execute("rm " .. destDir .. "temp")
			if iMarkedExecutable == nil then
				execute ("chmod +x " .. destDir .. "checksum")
			end
		end
		execute(destDir .. "checksum " .. destDir .. diskFile.name[iIndex] .. " > " .. destDir .. "temp")
		local res, openErr
		res, openErr = readfrom(destDir .. "temp")
		local checksum
		checksum = tonumber(read())
		readfrom() -- close the file
		--if diskNumber == 6 then
		--	MessageBox("Checksum is " .. tostring(checksum) .. " and we wanted " .. tostring(diskFile.checksum[iIndex]) .. " with file " .. diskFile.name[iIndex])
		--end
		if checksum ~= diskFile.checksum[iIndex] then
			return -91, diskFile.name[iIndex] .. " corrupt.\nGet new install disks."
		end

		iIndex = iIndex + 1 -- move on to next file
	end
	
	-- Decide which disk is next.
	-- As of hardware version 2, software version 3, we need to install different
	-- pchp.exe, adapters, main.sct, main.hlt. We will assume that the SWVersion
	-- variable reflects what version of software is required and, based on that, 
	-- can prompt for the correct disk. The code that makes this decision breaks 
	-- the generality of the code that we have heretofore enjoyed. We will assume
	-- the software for the newer hardware is on disk 2 and the software for the 
	-- older hardware is on disk 3.

	if diskNumber == 1 then
		if HardwareVersion == 1500 then
			diskNumber = 2		-- New hardware so disk 2
		else
			diskNumber = 3		-- Old hardware so disk 3
		end
	elseif diskNumber < 4 then
		diskNumber = 4 -- skip disk 2 or 3 as appropriate
	else
		diskNumber = diskNumber + 1 -- move on to the next disk
	end

	if diskNumber <= totalDisks then
		if RequireDisk(CheckContentsFile, diskNumber, diskNumber) == nil then
			return -90, diskNumber	-- one of the required disks can't be found
		else
			readfrom(sourceDir .. "contents.lst") -- We've opened the file OK once.  
				-- Don't need to check for errors since the file is cached.
			tonumber(read()) -- skip over disk number
		end
		
		if diskOfMessage ~= nil then
			setwidgittext(format(diskOfMessage, diskNumber, totalDisks), 4)
		end
	end
until diskNumber > totalDisks

-- Take the extra steps to install Linux if necessary
if iNeedToInstallLinux ~= nil then
	InstallLinux(destDir)
end	



-- At this point, fileNumber should be one greater than the actual number of files copied.
-- We new need to copy the new files from the temp directory, at the same time, we 
-- create a ver.txt file with all the files actually installed during the install process
-- so we can back them up during the next install.

if isRunningLinux then
	-- You can move but not delete an executing program in Linux.
	-- Move pchp out of the way.
	execute("rm " .. finalDir .. "pchp.old")
	execute("mv " .. finalDir .. "pchp " .. finalDir .. "pchp.old")
	readfrom(tempDir .. "/" .. "ver.txt")
else	
	readfrom(tempDir .. "\\" .. "ver.txt")	
end
writeto(finalDir .. "ver.fix")
newVersion = read()
write(newVersion .. "\n")

fileToCopy = 1
pushscreen()
openscreen(184)
copyingMessage = getwidgittext(3)
while fileToCopy < fileNumber do
	if isRunningLinux then
		sourceFile = tempDir .. "/" .. filesInTemp[fileToCopy]
	else
		sourceFile = tempDir .. "\\" .. filesInTemp[fileToCopy]	
	end
	destFile = finalDir .. filesInTemp[fileToCopy]
	setwidgittext(format(copyingMessage, filesInTemp[fileToCopy]), 3)

	errText = copyfile(sourceFile, destFile, 5)
	if errText ~= nil then
--		MessageBox(errText) -- For DEBUGGING only
		return -91, errText	-- -91 == copy file error, and some text
	end
	write(filesInTemp[fileToCopy] .. "\n")
	fileToCopy = fileToCopy + 1
end

readfrom()
writeto()

-- openscreen(popscreen())

-- Now we just need to clean up a little bit.

if isRunningLinux == nil then
	execute("del c:\\touch1\\pchp.com > nul")

	execute("del c:\\touch1\\ver.txt > nul")
	execute("copy c:\\touch1\\ver.fix c:\\touch1\\ver.txt > nul")
	execute("copy c:\\autoexec.bat c:\\autoexec.dt1 > nul")
	execute("copy c:\\touch1\\autoexec.bat c:\\autoexec.bat > nul")
	execute("copy c:\\touch1\\main.eng c:\\touch1\\main.sct > nul")
else
	execute("rm "..finalDir.."pchp.com")

	execute("rm "..finalDir.."ver.txt")
	execute("cp "..finalDir.."ver.fix "..finalDir.."ver.txt")
	execute("cp "..finalDir.."autoexec.bat /DOS/autoexec.bat")
	execute("cp "..finalDir.."main.eng "..finalDir.."main.sct")
	--writeto("/touch1.sh")  touch1.sh is updated above.
	--write("#!/bin/sh\ncd /DOS/touch1\n./pchp\n")
	--writeto()
	--execute("chmod +x /touch1.sh")
	execute("chmod +x " .. finalDir .. "pchp")

	-- Now we need to make sure that the hard disk is healthy.  This can
	-- only be done in DOS, so we set up the files to clean up after themselves
	-- the next time we boot up.
	execute("rm /lsav.bat")
	execute("rm /checkhd.bat") -- remove old check hd file
	execute("mv /linux.bat /lsav.bat")
	execute("cp "..finalDir.."linux.bat /linux.bat") -- replace the linux.bat file
	execute("cp "..finalDir.."checkhd.bat /checkhd.bat") -- copy check hd file

	-- update system files.  Dos name, linux name
	local theFiles = {{"net.cfg", "/etc/net.cfg.sample"},
					  {"exports", "/etc/exports"},
					  {"rc.mod",  "/etc/rc.d/rc.modules"},
					  {"rc.s",    "/etc/rc.d/rc.S"},
					  {"rc.ine",  "/etc/rc.d/rc.inet2"}}
	local iIndex = 1
	while iIndex <= 5 do
		execute("rm "..theFiles[iIndex][2]..".old") -- remove the old backup
		execute("cp "..theFiles[iIndex][2].." "..theFiles[iIndex][2]..".old")
		execute("rm "..theFiles[iIndex][2]) -- remove the original
		execute("cp "..finalDir..theFiles[iIndex][1].." "..theFiles[iIndex][2])
		iIndex = iIndex + 1
	end
	
	if DoesFileExist("/usr/bin/fdformat") then
	else
		execute("mv "..finalDir.."fdformat /usr/bin")
		execute("chmod +x /usr/bin/fdformat")
	end
	
	if DoesFileExist("/sbin/mkdosfs") then
	else
		execute("mv "..finalDir.."mkdosfs /sbin")
		execute("chmod +x /sbin/mkdosfs")
	end

	execute("chmod +x /etc/rc.d/rc.*") -- mark it executable
	execute("sync")	-- force all changes to be written to the disk
end

