home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Devil's Doorknob BBS Capture (1996-2003)
/
devilsdoorknobbbscapture1996-2003.iso
/
Dloads
/
PROGRAMM
/
BUILDER.ZIP
/
INSTALL.BLD
< prev
next >
Wrap
Text File
|
1992-11-17
|
55KB
|
1,616 lines
'==================================================================
' INSTALL.BLD
'
' What it does
' ------------
' This is a complete, ready-to-use installation program. While
' it's used to install Builder, it was designed to be easily
' dissected and altered for your own use.
' * Installation from any disk, to any disk
' * A help screen
' * Options for full vs. minimal installation (for users with
' limited disk space)
' * Data-driven: the configuration data file can create directories,
' change to them, and prompt to change disks. If you write your
' script correctly, you'll need to make only a few changes to the
' .BLD file.
' * Preset initial subdirectory for installation that the user can
' change
' * Tracks which files are installed and displays a complete
' status report on completion, listing which files, if any,
' didn't copy over
' * List of files to be installed in configuration data files,
' so they can be updated without changing or recompiling the
' install program
' * Configuration files may contain comments, so you can keep
' track of what files are included and why.
' * Configuration files handle disk changes
' * Configuration files may include descriptions of files to be
' printed along with the filename being copied.
' * User can interrupt installation anytime by pressing {Esc},
' or pause it by pressing {Space}.
' * User can confirm choices without continuing installation
' * User can change source drive, target drive, and target
' directory
' * Senses "disk not ready" conditions and insertion of wrong
' disks
' * Small--the compiled program requires less than 35K
' * Senses the video adaptor and sets colors accordingly
' * Detailed comments in the .BLD file explaining how to revise
' the script for your own use
' * Runs an included file viewer program called SHOW.EXE to
' display a README file
'
' The following files are expected to appear in the target directory
' - Data file
' - SHOW.EXE
' The installation script copies them over. It does not delete
' them on exit.
' Terms
' -----
' Here's an informal explanation of the terms used in this program.
'
' COMMENT: A line in the data file containing the "[" character. A
' comment line is ignored by the installation program and is there
' solely for those reading through the data file. It can be used
' to explain what the installation program does. Example comment
' line:
' [ Builder 1.50 installation data file for 5.25" diskette installations
'
' CONFIGURATION FILE: See DATA FILE
'
' DATA FILE: A file the installation program reads. It contains the names
' of files to be installed (that is, copied to the TARGET DIRECTORY),
' COMMENT lines, DESCRIPTION lines, and commands to make and change
' TARGET DIRECTORIES.
'
' DESCRIPTION LINE: A line in the installation file that appears
' onscreen while a file is being copied. It's displayed in boldface
' and contains the text "<bold>". Example description line:
' <bold>The Builder command-line compiler
'
' SOURCE DIRECTORY/DISK: The diskette from which files are copied.
' These are the diskettes you send out with your installation
' program.
'
' TARGET DIRECTORY: The directory files are copied into. There may
' be several target directories; the installation script can create
' them and change to them.
'
' The installation is driven by a data file. It lets you display
' descriptions of the files to be copied, include comments in the
' data file, and even control disk changes.
'
' File format
' ----------
' * File format for the data file:
' - Lines starting with [ aren't copied or displayed. They're comment
' lines.
' - Lines starting with <bold> are description lines, and are displayed
' while the file named on the next line is copied. Descriptions may
' be up to 45 chars and MUST be followed by a filename. Example:
'
' <bold>The Builder command-line compiler
' BLD.EXE
'
' - Anything else is thought to be a file and is copied over.
' - A line containing "CHANGE_DISK" means that a new disk must be inserted.
' It must be followed by these lines:
'
' 1. The volume label of the disk to be inserted (you can view or
' change the volume label using DOS's LABEL command). Make sure
' the case matches the case of the disk label (usually all uppercase).
' 2. A prompt, such ask "Please insert Disk 2 of 2".
' For example, the Builder script for 5.25" diskettes involves 2
' disks, with the volume labels "DISK 1" and "DISK 2". The lines
' in our FULL.DAT file are:
'
' Change disk
' DISK 2
' Please insert the disk labeled "Disk 2 of 2".
'
' If the correct diskette isn't inserted, the prompt continues until
' it is.
'
' - A line containing the text "CHANGE_TARGET_DIR" should be followed by
' the name of an existing target directory. The next line should
' contain the name of the directory to change to. See also
' MAKE_TARGET_DIR. Example:
' [ Change back to the original target directory.
' CHANGE_TARGET_DIR
' [ Go back to the Builder directory.
' ..
' - A line containing the text "MAKE_TARGET_DIR" should be followed by
' the name of a target directory to be created. The next line should
' contain the name of the directory to create. If the target directory
' already exists, nothing is done. If it doesn't exist, it's created.
' Example:
' [ Create the directory EXAMPLES
' MAKE_TARGET_DIR
' EXAMPLES
'
' Notes
' -----
' Only description lines should contain the string "<bold>".
' Only comment lines should contain "["
' Only CHANGE_DISK lines should contain the text "CHANGE_DISK"
' Only MAKE_TARGET_DIR lines should contain the text "MAKE_TARGET_DIR".
' Only CHANGE_TARGET_DIR lines should contain the text "CHANGE_TARGET_DIR".
'
' By:
' Tom Campbell, Doug Amaral
'
'==================================================================
' InFile is the data file containing filenames, sizes, etc.
' CheckFile is the output file containing files that didn't make it.
File InFile, CheckFile
' BothReady is set to 1 only if both SourceDrive and TargetDrive are
' ready.
' BoxWidth is used to adjust the size of boxes.
' CorrectParams is 0 until source drive, target drive, and directory
' are okay.
' DiskStatus flags readiness of source and target drives.
' FullInstall is 1 for a full installation, 2 for minimal installation.
' InstallError is 0 if no files were installed, 1 if some were installed,
' 2 if all were installed. "All" means the set of files listed in either
' the Full or Minimal installation option, whichever was chosen.
' InstFileCount is the # of files that *should* be copied from the source
' disk to the target directory. It's given in the install file.
' Lines in the data file starting with "]" are called description lines.
' When GetNextLine reads in such a line, IsDescription is set to 1.
' Otherwise, it's cleared to 0.
' Missing is set to the number of files that should have been copied from
' the source directory to the target directory, but somehow weren't.
' MsgLen is used for length of command line params.
' NumOfFiles is the # of files this installation procedure should copy.
' It's the first non-comment line of the installation file.
' ShouldCopy is set to 1 if the next line read from the data file is
' is a filespec that should be copied to the target. It's cleared to 0
' for other lines, such as comments or description lines.
Integer BothReady, BoxWidth, DiskStatus, CorrectParams
Integer FullInstall, InstallError, InstFileCount, IsDescription
Integer Missing, MsgLen, NumOfFiles, ShouldCopy
Integer Copying
' LongVal is the converted value of a number read in from a file. Since
' Builder can't currently read a number directly from a file, it has
' to be converted from string to integer. This is the value returned.
longint FullSize, LongVal, MinSize
' CorrectLabel is the label of the disk to be inserted.
' Disk1 is the volume label for disk 1 of the installation.
' DiskPrompt is used by CorrectDrive. it's the prompt displayed for
' the user to insert a diskette.
' DriveSpec is used by the routine ValidateDrive, which makes sure
' a drive is specified correctly.
' CheckName is the name of the file that tracks which files got written
' out; it's used to verify the list of files copied once the copy
' procedure is finished.
' InstName is the name of the input data file.
' Msg is used for dialogs whose text changes.
' NextLine holds line as it's read from the install data file.
' Scratch is a general-purpose string variable. Assume its value will
' be lost between SUB invocations.
' ScreenType holds adaptor type, as returned by the Adaptor function.
' SourceDrive is the floppy Builder is installed from (defaults to A).
' Target is the drive and path where files are installed.
' TargetDir is the directory Builder will be copied to.
' TargetDrive is the volume Builder is installed to (defaults to C).
' TargetFile is the fully qualified filename of the file being copied
' to its target directory, such as "C:\BUILDER\BLD.EXE".
String CheckName, CorrectLabel, Disk1, DiskPrompt, DriveSpec, InstName
String Msg, NextLine, Scratch, ScreenType, SourceDrive, Target, TargetDir
String TargetDrive, TargetFile, Scratch1, Hold, InputIt
' Just change these variables to alter default values.
String DefSourceDrive, DefFullFile, DefMinFile, DefTargetDrive, DefTargetDir
LongInt DiskAvail,NeededSpace
String CurrentDisk
'==================================================================
'
' 1. DEVELOPER-DEFINED VARIABLES--INITIAL SETTINGS
'
' The variables initialized in this section need only be changed
' here; you can and should leave them alone in the rest of the
' program. This localizes changes that need to be made to this
' script. They are never changed by the user.
'
' These serve the same purpose as named constants in other
' languages; since Builder currently lacks them, variables are used
' instead.
'
' These variables are listed in alphabetical order within this
' section.
'
'==================================================================
' Name of output file that tracks files copied. This file will be
' deleted if all files are installed properly.
CheckName := "MISSING.TXT"
' Filename used for full installation option.
DefFullFile := "FULL.DAT"
' Filename used for minimal installation option.
DefMinFile := "MINI.DAT"
' Volume label of the first distribution diskette.
Disk1 := "DISK 1"
'==================================================================
'
' 2. USER-DEFINED VARIABLES--INITIAL SETTINGS
'
' The variables initialized in this section need only be changed
' here; you can and should leave them alone in the rest of the
' program. This localizes changes that need to be made to this
' script.
'
' The installation script offers the user to change them at the
' appropriate time; they consist of things like directory names
' and the drive letters of disk used to copy from (never
' hard code values like the disk used to copy from).
'
' These variables are listed in alphabetical order within this
' section.
'
'==================================================================
' Drive to install from (the user can change this later).
DefSourceDrive := "A"
' Drive to install to (the user can change this later).
DefTargetDrive := "C"
' Directory to install to (the user can change this later).
DefTargetDir := "\BUILDER"
'==================================================================
'
' These initializations should be left as is, with the possible
' exception of Target.
'
'==================================================================
' 0 if no files copied, 1 if some files copied, 2 if all copied.
InstallError := 0
' Value of next integer read in from file. Set to known quantity.
LongVal := 0
ScreenType:=Adaptor
' Missing is set to the number of files that should have been copied from
' the source directory to the target directory, but somehow weren't.
' Starts off at 0, of course.
Missing := 0
' Full pathane of directory to install to.
Target := DefTargetDrive + ":" + DefTargetDir
SetMenuColors
' Collect any command line parameters and force them to uppercase.
Put UpperCase "%1" Into SourceDrive
Put UpperCase "%2" Into TargetDrive
Put UpperCase "%3" into TargetDir
' If any params were missing, fill in with reasonable defaults.
if SourceDrive is "" SourceDrive := DefSourceDrive
if TargetDrive is "" TargetDrive := DefTargetDrive
if TargetDir is "" TargetDir := DefTargetDir
CurrentDisk:=CurrentDrive
If ((CurrentDisk=="B:") AND ("%1"=="")) SourceDrive:="B"
'Check to see if the drives have no colons and if the directory has a leading
'backslash
if (SourceDrive Contains ":") SourceDrive:= MidStr SourceDrive,1,1
if (TargetDrive Contains ":") TargetDrive:= MidStr TargetDrive,1,1
'Grab the first character of the string
Hold:= Midstr TargetDir,1,1
'Insert a leading backslash if one does not exist
if Hold<>"\" TargetDir:="\"+TargetDir
' Assume user input, if any, is incorrect.
Put 0 into CorrectParams
' Assume full installation.
Put 1 into FullInstall
' Initialize for the very first call to RedrawMsgArea
SetMenuColors
BoxWidth := 30
' Put up the banner and menu's help.
RedrawMsgArea
' This is the main loop.
While 1
' Use the standard white text on a black background if it's a mono
' screen.
If ScreenType is "Mono"
CLS
end else
' If it's a color screen, use a blue background.
CLS White On Blue
end
' Display title for this program.
RedrawMsgArea
' Create a dropdown menu in the middle of the screen. No title.
DoMainMenu
End
' Displays main menu and dispatches input. Does it only once; another
' loop must repeat this process until Quit command is issued.
Sub DoMainMenu
' Adjust menu colors to screen type.
SetMenuColors
' The menu is a box--no title--in the center of the screen.
Dropdown "" @ 8, 29
Item "Full Installation"
' Use full, not minimal, installation.
Put 1 into FullInstall
Put 1100000 into NeededSpace
DoInstall
Item "Minimum Installation"
Put 2 into FullInstall
Put 950000 into NeededSpace
DoInstall
Item "Help"
DoHelp
Item "Show choices"
' Disable hardware text cursor.
Don't use cursor
DisplayParams
GetKey
Use cursor
' Item "Documentation Update"
' run show readme.txt
Item "Quit"
CloseUp
End ' DropDown
End ' Sub DoMainMenu
'==================================================================
' 3. SUB DoHelp -- CHANGE THIS TO SUIT YOUR OWN APPLICATION
'
' What it does:
' Displays a single help screen. Draws a box in color if it's a
' color system and BW if it's a mono system.
'
' Globals affected:
' STRING ScreenType
'
'==================================================================
Sub DoHelp
' Disable hardware text cursor.
Don't use cursor
' Draw a white on black box in a mono system.
If ScreenType contains "Mono"
Single Box 6, 5, 72, 15 White on Black
Text Bright White on Black
' Draw a yellow on black box in a color system.
end else
Single Box 6, 5, 72, 15 Blue on White
Text Blue on White
end
Say @ 7, 31 "<black>About installation"
Say @ 9, 9 "Full installation: Builder and example directory (1.1M)"
Say @ 10, 9 "Minimum installation: Builder and help files only (950K)"
' Say @ 11, 9 "Documentation Update: Bug list and new features"
Say @ 11, 9 "Quit: Exit this installation program."
Say @ 15, 9 "To make a choice, move the {Up} or {Down} keys and press {Enter}."
Say @ 16, 9 "If you have a mouse, click the left button on the appropriate"
Say @ 17, 9 "choice."
Say @ 19,23 "<reverse> Press {Enter} to return to main menu ";
GetKey
End ' Sub DoHelp
'==================================================================
' SUB ChangeDisk
'
' What it does:
' Responds to a "CHANGE_DISK" line. Expects that the next lines
' will be a volume label, then a prompt. Displays the prompt,
' then waits for a disk with that volume label to be inserted.
' If the wrong disk is inserted, redisplays the prompt.
'
' Globals affected:
' STRING Msg, NextLine
'
' Other routines called:
' GetNextLine
'
'==================================================================
Sub ChangeDisk
' Get the next non-comment line from the disk and copy to the
' variable NextLine.
GetNextLine
' This is the volume to check.
CorrectLabel := NextLine
' Get the next non-comment line from the disk and copy to the
' variable DiskPrompt.
GetNextLine
' This is the volume to check.
DiskPrompt := NextLine
' Loop until the correct disk is inserted or user presses {Esc}.
BothReady := 0
While BothReady is 0
CorrectDrive
End
Double Box 17, 7, 68, 9 White on Black
Text Bright White on black
say @ 18, 9 "<bold>Now copying files. Press {Space} to pause or {Esc} to quit."
End ' Sub ChangeDisk
'==================================================================
' SUB CheckDrives
'
' What it does:
' Checks both source and target drives.
' Displays an error message for each drive that's not ready.
' If both are ready, sets BothReady to 1. If either is not
' ready, sets it to 0.
'
' Globals affected:
' INTEGER BothReady, DiskStatus
' STRING Msg, SourceDrive, TargetDrive
'
' Other routines called:
' ErrMsg
'
'==================================================================
Sub CheckDrives
' Assume at least 1 drive isn't ready.
Put 0 into BothReady
' Check floppy we're supposed to install from.
Put DiskReady SourceDrive into DiskStatus
' Check floppy for readiness.
If DiskStatus is 0
' Put up an error dialog if it's not ready.
Msg := "Disk " + SourceDrive + " isn't ready."
ErrMsg
end else
' Check the directory files will be copied to.
Put DiskReady TargetDrive into DiskStatus
' Display an error message if the target drive isn't ready.
If DiskStatus is 0
Msg := "Disk " + TargetDrive + " isn't ready."
ErrMsg
end else
' Both are ready, so give it the go-ahead.
While CorrectParams is 0
' Ask if that's the drive to install to.
Msg := "Copy files to drive " + TargetDrive + "? (Y/N)"
GetYNMessage
' Assume user input will be bad.
' Repeat until input is valid.
' If user pressed, Y, then assume this is correct input.
If DOSErrorLevel is 1
Put 1 into CorrectParams
end else
Put 0 into CorrectParams
Put "Drive to copy files to? " into Msg
InputDriveLetter
TargetDrive := DriveSpec
End ' If DOSERRORLEVEL
End ' While CorrectParams
Put 1 into BothReady
End ' If DiskStatus
End ' If DiskStatus
End ' Sub CheckDrives
'==================================================================
' SUB CheckPause
'
' What it does:
' Checks for a keypress. If no keypress, cool. If the keypress
' is {Esc}, halts installation process. If the keypress is the
' space bar, asks the user to halt installation and quits if
' user types {Y}.
'
' Globals affected:
' INTEGER BoxWidth
' STRING Msg
'
' Other routines called:
' GetYNMessage
'
'==================================================================
Sub CheckPause
' Quit this routine if no key was pressed.
if Keypressed
' A key was pressed. Remove it from the keyboard buffer.
GetKey
' Quit immediately if it's the {Esc} key.
If LastKey is {Esc} CloseUp
' If it's the space bar,
If LastKey is { }
' ask the user if she wants to quit.
Msg := "Would you like to cancel installation? (Y/N)"
GetYNMessage
' If user pressed, Y, then quit.
If DOSErrorLevel is 1
CloseUp
end ' If DOSErrorLevel
Double Box 17, 7, 68, 9 White on Black
Text Bright White on black
say @ 18, 9 "<bold>Now copying files. Press {Space} to pause or {Esc} to quit."
end ' If Lastkey
end ' If Keypressed
End ' Sub CheckPause
'==================================================================
' SUB CloseUp
'
' What it does:
' Displays a sign-off message at the top of the screen.
' Writes an EOF to CheckFile, since SHOW.EXE requires it.
' Closes all files.
' Deletes the check file (which contains the list of missing
' files) if none is missing.
'
' Globals used:
' INTEGER Missing
'
' Other routines called:
' GetYNMessage
'
'==================================================================
Sub CloseUp
If Missing
' Convert the # of files that didn't make it to an integer.
Msg := IntToStr Missing
Msg := Msg + " files weren't copied over. View the list of those missing files? "
GetYNMessage
If DOSErrorLevel is 1
' Write an EOF to the list of missing files, if any.
WriteLine "~26" to CheckFile
System Target+"\Show " + Target+"\"+CheckName
End
end else
' No files missing. Delete that file.
System "if exist " + CheckName + " del " + CheckName
End ' If Missing
' Clear the screen.
cls
' Print sign-off message
SayGoodbye
' Restore the text cursor.
Use cursor
' Return all file resources to DOS.
CloseAllFiles
' Return to the operating system.
Exit
End ' Sub Closeup
'==================================================================
' SUB CorrectDrive
'
' What it does:
' Checks DriveSpec for CorrectLabel. If the disk in DriveSpec
' has the wrong label, puts up an error message, and sets
' BothReady to 0. Otherwise, sets BothReady to 1.
'
' If user presses {Esc}, quits the program by calling CloseUp.
'
' Globals affected:
' INTEGER BothReady
' STRING CorrectLabel, DiskPrompt, DriveSpec, Msg, SourceDrive
'
' Other routines called:
' CloseUp, ErrMsg, ShowMsgBox
'
'==================================================================
Sub CorrectDrive
' Get the label of the disk in the drive being installed from.
' Get its label.
Put DiskLabel SourceDrive into DriveSpec
' Is it the correct one?
If DriveSpec <> CorrectLabel
' Nope. Issue an error message.
Msg := DiskPrompt
ShowMsgBox
' Set error flag.
Put 0 into BothReady
end else
' Correct disk was inserted. Everything's cool.
Put 1 into BothReady
End
' Quit if user pressed {Esc}.
If LastKey is {Esc} CloseUp
End ' Sub CorrectDrive
'==================================================================
' SUB CreateDirectories
'
' What it does:
' Creates the target directory, whose name is in Target and
' sets DiskStatus to 1. If unable to create the target
' directory, sets DiskStatus to 0.
'
' Globals affected:
' INTEGER DiskStatus
' STRING Target
'
' Other routines called:
' ErrMsg
'
'==================================================================
Sub CreateDirectories
' MD will issue a non-redirectable error message if the directory
' already exists, so check for it first. DiskStatus will be 1 if
' the directory is already there, and 0 if not.
DiskStatus := DirExists Target
' Create the directory if it's not there already.
If DiskStatus is 0
System "MD " + Target + " >nul"
end
' Just to be on the safe side, make sure the directory is there.
' By all rights it should be.
Put DirExists Target into DiskStatus
End ' Sub CreateDirectories
'==================================================================
' SUB DisplayParams
'
' What it does:
' Display options for SourceDrive, TargetDir, TargetDrive and
' installation option (Full or Minimal).
'
'==================================================================
Sub DisplayParams
' Draw a long box (long enough to hold pathnames) below the menu.
Double Box 17, 7, 68, 9 White on Black
Text Bright White on black
say @ 18, 23 "<yellow>Confirming your installation options:"
say @ 20, 9 "Install from drive <bold>"; SourceDrive; ":"
say @ 21, 9 "Copy files to <bold>"; Target
If FullInstall == 1
say @ 22, 9 "Installation: <bold>Full";
end else
say @ 22, 9 "Installation: <bold>Minimum";
End ' If FullInstall
End ' Sub DisplayParams
'==================================================================
' SUB ErrMsg
'
' What it does:
' Displays a box in the upper left of the screen. Prints
' "Problem:" at the top, then displays Msg in the box. Prints
' "Press {Enter} to continue" at the bottom of the box, then
' waits for a keypress. Draws a blank box over this one at the
' end, thus reblanking that portion of the screen.
'
' Globals affected:
' INTEGER BoxWidth
' STRING Msg
'
'==================================================================
Sub ErrMsg
' Disable hardware text cursor.
Don't use cursor
' Get the length of the string in Msg and write it to BoxWidth, so the
' width of the box can be customized.
Put Length Msg into BoxWidth
' Account for word "<bold>Problem: "
BoxWidth := BoxWidth + 10
' Make sure it's wide enough for the "Press" message.
If BoxWidth < 26 Put 26 into BoxWidth
' Draw a box in the upper left corner.
Put BoxWidth + 4 into BoxWidth
Double Box 2, 2, BoxWidth, 5 Bright White on Black
' Use bright white text on a black background.
Text Bright White on Black
Say @ 3, 4 "<bold>Problem: ";
' Display the message starting at the left side of the box, leaving a
' space of breathing room.
Say Msg;
Say @ 5, 4 "<bold>Press {Enter} to continue.";
' Await a keystroke.
GetKey
' Redraw over the box.
RedrawMsgArea
' Enable hardware text cursor.
Use cursor
End ' Sub ErrMsg
'==================================================================
' SUB GetAndConfirmParams
'
' What it does:
' Calls GetParams to get and verify user's choices of source
' drive, target drive, etc., then shows them using DisplayParams
' and requests confirmation. If user confirms choices fine; if
' not, asks for them again.
'
' Globals affected:
' INTEGER CorrectParams
'
' Other routines called:
' GetParams, DisplayParams
'
'==================================================================
Sub GetAndConfirmParams
' Assume the parameters will be changed.
Put 0 into CorrectParams
While CorrectParams is 0
' Get user's choices.
GetParams
' Show them.
DisplayParams
Say @ 24, 28 "<reverse>Are these correct? (Y/N) ";
GetYN
' Can't use IF ERRORLEVEL because we need an ELSE.
If DOSErrorLevel is 1
Put 1 into CorrectParams
end else
Put 0 into CorrectParams
End
End
End ' Sub GetAndConfirmParams
'==================================================================
' SUB GetDrives
'
' What it does:
' Gets input for SourceDrive and TargetDrive. It doesn't check
' for valid drives, but it does check that there's input for each
' one. If there's input for each one, puts 1 into CorrectParams.
' If one or more is missing, puts 0 into CorrectParams.
'
' Globals affected:
' INTEGER CorrectParams
' STRING DriveSpec, SourceDrive, TargetDrive
'
' Other routines called:
' GetYNMessage, InputDriveLetter
'
'
'==================================================================
Sub GetDrives
' Ask if that's the drive to install from.
Msg := "Install from drive " + SourceDrive + "? (Y/N)"
GetYNMessage
' Assume user input will be bad.
Put 0 into CorrectParams
' Repeat until input is valid.
While CorrectParams is 0
' If user pressed, Y, then assume this is correct input.
If DOSErrorLevel is 1
Put 1 into CorrectParams
end else
Put 0 into CorrectParams
Put "Drive to install from? " into Msg
InputDriveLetter
SourceDrive := DriveSpec
End ' If DOSERRORLEVEL
End ' While CorrectParams
' Ask if that's the drive to install to.
Msg := "Copy files to drive " + TargetDrive + "? (Y/N)"
GetYNMessage
' Assume user input will be bad.
Put 0 into CorrectParams
' Repeat until input is valid.
While CorrectParams is 0
' If user pressed, Y, then assume this is correct input.
If DOSErrorLevel is 1
Put 1 into CorrectParams
DiskAvail:=DiskFree TargetDrive
if DiskAvail < NeededSpace
Msg := "Not Enough room on "+TargetDrive+" to install"
ErrMsg
Put 0 into CorrectParams
end
end else
Put 0 into CorrectParams
Put "Drive to copy files to? " into Msg
InputDriveLetter
TargetDrive := DriveSpec
End ' If DOSERRORLEVEL
End ' While CorrectParams
End ' Sub GetDrives
'==================================================================
' SUB GetDirectory
'
' What it does:
' Puts up a box, requesting the name of a directory.
' Returns 1 in CorrectParams if a valid dir is entered, 0 if not.
' Writes directory name to TargetDir.
'
' Globals affected:
' INTEGER CorrectParams
' STRING Msg, TargetDir
'
' Other routines called:
' ErrMsg, GetYNMessage
'
'==================================================================
Sub GetDirectory
' Assume bad input.
Put 0 into CorrectParams
While TargetDir is ""
Msg := "Copy to what directory? Examples: \BUILDER or \UTIL\BUILDER"
GetString
TargetDir := InputIt
If TargetDir is ""
Put 0 into CorrectParams
Msg := "You must enter a path. Examples: \BUILDER or \UTILS\NEW\BUILDER"
ErrMsg
TargetDir := ""
end
End
If TargetDir contains ":"
Msg := "Please don't include a drive specification. Just a directory."
ErrMsg
Put "" into TargetDir
end else
Put 1 into CorrectParams
End ' If TargetDir
'Grab the first character of the string
Hold:= Midstr TargetDir,1,1
'Insert a leading backslash if one does not exist
if NOT (Hold=="\") TargetDir:="\"+TargetDir
' Force directory name to uppercase.
Put UpperCase TargetDir into TargetDir
If TargetDir <> ""
' Ask if that's the directory to install to.
Msg := "Install to directory " + TargetDir + "? (Y/N)"
GetYNMessage
' If user pressed, Y, then assume this is correct input.
If DOSErrorLevel is 1
Put 1 into CorrectParams
end else
Put 0 into CorrectParams
Put "" into TargetDir
End ' If DOSERRORLEVEL
End ' If TargetDir
End ' Sub GetDirectory
'==================================================================
' SUB GetNextLine
'
' What it does:
' Gets the next line from the file and copies it to the string
' variable NextLine. If the line contains "[", which is illegal
' in a filename, it's thrown out and another line is read in.
' Use this each time you need to get information from the file,
' since a comment line can appear anywhere.
'
' If the line contains "<bold>", the IsDescription flag is set
' to 1. If not, it's set to 0. If the line is a filespec
' that should be copied to the target, ShouldCopy is set to 1.
' If it's anything else, such as a description or comment
' line, ShouldCopy is cleared to 0.
'
' If the line contains "CHANGE_DISK", calls ChangeDisk.
'
' Globals affected:
' FILE Infile
' INTEGER IsDescription, MsgLen, ShouldCopy
' STRING Msg, NextLine
'
'==================================================================
Sub GetNextLine
' Read a line of text from the file whose descriptor is
' InFile. Copy it to the string variable NextLine.
If not eof InFile ReadLine NextLine from Infile
' Strip out this an all succeeding comment lines if it starts with the
' comment character.
While NextLine contains "["
' As long as there's an asterisk anywhere in the line, throw
' the line out and collect another one.
If not eof InFile ReadLine NextLine from Infile
' This line should not be copied to the target.
Put 0 into ShouldCopy
end ' While NextLine
' Assume this line should be copied over--that it's a valid
' filespec.
Put 1 into ShouldCopy
' Assume it's not a description line.
Put 0 into IsDescription
' Not a comment line. Force it to uppercase.
Put UpperCase NextLine into Scratch
' Flag whether it's a description line.
If Scratch contains "<BOLD>"
Put 1 into IsDescription
' This line should not be copied to the target.
Put 0 into ShouldCopy
end
if Scratch Contains "CHANGE_DISK"
ChangeDisk
Put "" into NextLine
Put 0 into IsDescription
Put 0 into ShouldCopy
end
if Scratch Contains "MAKE_TARGET_DIR"
MakeDir
Put "" into NextLine
Put 0 into IsDescription
Put 0 into ShouldCopy
end
if Scratch Contains "CHANGE_TARGET_DIR"
ChangeDir
Put "" into NextLine
Put 0 into IsDescription
Put 0 into ShouldCopy
end
if Scratch Contains "RUN_EXTRACTION"
Extraction
Put "" into NextLine
Put 0 into IsDescription
Put 0 into ShouldCopy
end
' If the line is empty, don't copy.
MsgLen := Length NextLine
If MsgLen is 0
Put "" into NextLine
Put 0 into ShouldCopy
Put 0 into IsDescription
end
End ' Sub GetNextLine
'==================================================================
' SUB GetParams
'
' What it does:
' Ensures there is some sort of input in SourceDrive and
' TargetDrive. If not, calls GetDrives. Once that input has been
' secured, it's checked here. Does same for TargetDir; if none
' is given, gets one and validates it.
'
' Globals affected:
' INTEGER CorrectParams
' STRING Target, TargetDir, TargetDrive
'
' Other routines called:
' GetDirectory, GetDrives
'
'==================================================================
Sub GetParams
' Make sure at least that SourceDrive, TargetDrive are input.
' Ensure they're valid.
' Assume the drive specs are invalid.
Put 0 into CorrectParams
' Keep trying until valid drive letters are input.
While CorrectParams is 0
' GetDrives writes 1 to CorrectParams when drive specs are valid.
GetDrives
End
' Keep trying until a target directory has been input.
Put 0 into CorrectParams
While CorrectParams is 0
GetDirectory
End
' Create a full path for the install files to be copied to.
' For example: C:BUILDER
Put TargetDrive + ":" + TargetDir into Target
End ' Sub GetParams
'==================================================================
' SUB GetString
'
' What it does:
' Displays a box in the upper left of the screen.
' Displays Msg in the box. Awaits user input of a string.
' Draws a blank box over this one at the end, thus reblanking
' that portion of the screen. Returns string in system variable
' It.
'
' Globals affected:
' INTEGER BoxWidth
' STRING Msg
'
'==================================================================
Sub GetString
' Get the length of the string in Msg and write it to BoxWidth, so the
' width of the box can be customized.
Put Length Msg into BoxWidth
' Make sure it's wide enough for the "Press" message.
If BoxWidth < 26 Put 26 into BoxWidth
' Draw a box in the upper left corner.
' Add 40 for the string.
Put BoxWidth + 4 + 40 into BoxWidth
' Make sure box isn't too wide.
If BoxWidth > 77 Put 77 into BoxWidth
Double Box 2, 2, BoxWidth, 7 Bright White on Black
' Use bright white text on a black background.
Text Bright White on Black
' Display the message starting at the left side of the box, leaving a
' space of breathing room.
Say @ 5, 4 Msg;
RowCol 6, 4
Repeat 50
' This is Alt-249
Say "∙";
End
RowCol 6, 4
' Get the string from the keyboard.
input InputIt
' Redraw over the box.
RedrawMsgArea
End ' GetString
'==================================================================
' SUB GetYNMessage
'
' What it does:
' Displays Msg in a custom-sized box. Appends a space.
' Awaits a {Y} or {N} keypress.
' Undraws box after user types {Y} or {N}.
' If User types {Y}
'
' Globals affected:
' INTEGER BoxWidth
' STRING Msg
'
' Other routines called:
' GetYN
'
'==================================================================
Sub GetYNMessage
' Get the length of the string in Msg and write it to BoxWidth, so the
' width of the box can be customized.
Put Length Msg into BoxWidth
' Add for padding on left & right, as well as box sides.
Put BoxWidth + 6 into BoxWidth
' Make sure box isn't too wide.
If BoxWidth > 77 Put 77 into BoxWidth
Double Box 2, 2, BoxWidth, 7 Bright White on Black
' Use bright white text on a black background.
Text Bright White on Black
' Display the message starting at the left side of the box, leaving a
' space of breathing room.
Say @ 5, 4 Msg + " ";
GetYN
' Redraw over the box.
RedrawMsgArea
End ' Sub GetYNMessage
'==================================================================
' SUB InputDriveLetter
'
' What it does:
' Displays Msg in a box, then awaits input. If input is null or
' invalid, keeps going until valid input (consisting of a single
' drive letter) is received. String is copied to DriveSpec. Sets
' CorrectParams to 0 on error, 1 on success.
'
' Globals affected:
' INTEGER CorrectParams
' STRING DriveSpec
'
' Other routines called:
' GetString, ValidateDrive
'
'==================================================================
Sub InputDriveLetter
' Display Msg, get a string from keyboard, and copy into system global It.
GetString
' Copy to temporary.
DriveSpec := InputIt
' Make sure DriveSpec is valid.
ValidateDrive
' Force to uppercase.
Put Uppercase DriveSpec into DriveSpec
if CorrectParams is 0
Msg := "Please enter a drive letter with no colon."
' Display error message in a dialog and await a keypress.
ErrMsg
End ' If
End ' Sub InputDriveLetter
'==================================================================
' SUB SetMenuColors
'
' What it does:
' Set menu style to B&W combination for mono systems, or a more
' patriotic red/white/blue color set for other systems.
'
' Globals affected:
' STRING ScreenType
'
'==================================================================
Sub SetMenuColors
If ScreenType is "Mono"
' Item text: Black
' Item background: White
' Hotkey text: Black
' Hotkey background: White
' Highlight text: White
' Highlight background: Black
' Immediate trigger: Off (requires {Enter} key
' First key is trigger: Yes
' Box style: Single
' Shadow: Yes
Menu Style Black,White,Black,White,White,Black,Black,White,0,1,1,1
end else
Menu Style Blue,White,Red,White,White,Black,Black,White,0,1,1,1
' | | | | | | | | | | | |
' | | | | | | | | | | | Shadow: Yes
' | | | | | | | | | | Box: Single
' | | | | | | | | | Trigger 1st: Yes
' | | | | | | | | Imm. trigger: Off
' | | | | | | | Box background: White
' | | | | | | Box color: Black
' | | | | | Highlight background: Black
' | | | | Highlight text: White
' | | | Hotkey background: White
' | | Hotkey text: Red
' | Item background: White
' Item text: Blue
End
End
'==================================================================
' SUB ShowMsgBox
'
' What it does:
' Displays Msg in a custom-sized box. Appends a space. Awaits
' a keystroke, and afterward, "undraws" the box.
'
' Globals affected:
' INTEGER BoxWidth
' STRING Msg
'
' Other routines called:
' GetYN
'
'==================================================================
Sub ShowMsgBox
' Get the length of the string in Msg and write it to BoxWidth, so the
' width of the box can be customized.
Put Length Msg into BoxWidth
' Add for padding on left & right, as well as box sides.
Put BoxWidth + 6 into BoxWidth
' Make sure box isn't too wide.
If BoxWidth > 77 Put 77 into BoxWidth
Double Box 2, 2, BoxWidth, 7 Bright White on Black
' Use bright white text on a black background.
Text Bright White on Black
' Display the message starting at the left side of the box, leaving a
' space of breathing room.
Say @ 5, 4 Msg + " ";
' Await a keypress.
GetKey
' Redraw over the box.
RedrawMsgArea
End ' Sub GetYNMessage
'==================================================================
' SUB ValidateDrive
'
' What it does:
' Ensures the string DriveSpec contains a single letter.
' Sets CorrectParams to 1 if the drive is valid, 0 if not.
' If the drive is invalid, prints an error message.
'
' Globals affected:
' INTEGER CorrectParams, MsgLen
' STRING DriveSpec
'
'==================================================================
Sub ValidateDrive
' Assume DriveSpec is invalid.
Put 0 into CorrectParams
' Now we have a source and a target drive. Validate them:
If not (DriveSpec contains ":")
' Make sure there's only 1 letter in the drive specification.
Put Length DriveSpec into MsgLen
' If it's a single letter, everything's cool.
If MsgLen is 1 CorrectParams := 1
End ' If not
End ' Sub ValidateDrive
'==================================================================
' SUB CopyFiles
'
' What it does:
' Checks source and target drives, then copies the installation
' data file (which contains the list of filenames) to the
' target directory. After that, begins the actual
' process of copying files from the source floppy to the
' target directory. Closes InFile when finished.
'
' Appends colon to SourceDrive, turning it, for example, into
' "A:" from "A". Same with TargetDrive.
'
' Returns:
' 0 in BothDrives if one of the drives isn't ready
'
' At this point we know:
' * The target directory is available or has been created.
' * The source and target drives are ready.
'
' Globals affected:
' FILE InFile
' INTEGER BothReady, IsDescription
' STRING CorrectDrive, CorrectLabel, DiskStatus, DriveSpec,
' InstName, NextLine, SourceDrive, TargetDrive
'
' Other routines called:
' CheckDrives, CorrectDrive, ErrMsg
'
'==================================================================
Sub Copyfiles
' Disable hardware text cursor.
Don't use cursor
' Ensure both source and target drives are ready.
' Print an error message and quit this routine if either drive isn't
' ready.
If BothReady is 0
Put "Both drives must be working to install." into Msg
ErrMsg
end else
If BothReady is 0
'Put "Please insert the disk labeled " + CorrectLabel into Msg
'ErrMsg
end else
' Make SourceDrive and TargetDrive real drive specs by
' appending colons.
SourceDrive := SourceDrive + ":"
TargetDrive := TargetDrive + ":"
' Copy the installation file to the target drive.
System "Copy " + SourceDrive + InstName + " " + Target + " > nul"
' Change to the target drive and directory.
System TargetDrive
System "CD " + Target
' DiskStatus is 0 if there's a problem.
Put 1 into DiskStatus
' Make sure the install file got copied correctly.
Open InstName for Reading as Infile
' Create a file to be written as files are copied.
Open CheckName for Writing as CheckFile
' Write a header to that file.
WriteLine "Files missing from " + Target to CheckFile
Double Box 17, 7, 68, 9 White on Black
Text Bright White on black
say @ 18, 9 "<bold>Now copying files. Press {Space} to pause or {Esc} to quit."
say @ 21, 9 "Copying file <bold>"; NextLine; " to <bold>"; Target
say @ 22, 9 "DOS messages: ";
' Continue only if everything's okay.
If DiskStatus is 1
While Not EOF InFile
' Copy the next line of the file into the variable NextLine.
' Ignore comment lines in the data file.
GetNextLine
' If it's a description line (we know because the line contains
' the <bold> metacharacter), display it verbatim. This lets us
' identify the file being copied.
if IsDescription
' Blank out the previous description.
say @ 20, 9 " "
' Display this description.
say @ 20, 9 NextLine
' Get the next line, which MUST be a filename.
' Ignore comment lines in the data file.
GetNextLine
end
' Copy this if it's a valid filespec. Don't copy if it's a
' description or comment line.
If ShouldCopy is 1
' Let the user halt the copy procedure.
CheckPause
' Undraw any previous text drawn on this line.
say @ 21, 21 " "
' Display the name of the next file to be copied in boldface.
say @ 21, 21 " <bold>"; NextLine; " to <bold>"; Target
' Copy the file to the target drive.
RowCol 22, 22
System "Copy " + SourceDrive + NextLine + "/B " + TargetDrive + " /B /V > nul"
' We know that at least 1 file made it.
InstallError := 1
' Track the filename that was copied.
' Build up a name consisting of the target directory and the
' filename.
TargetFile := Target + "\" + NextLine
' If the file wasn't copied over, increment the counter of # of
' files that didn't make it.
DiskStatus := 0
If Not exist TargetFile DiskStatus := 1
' If file wasn't copied over, write
If DiskStatus is 1
' Track the # of files not found.
Missing := Missing + 1
' Copy its name to a list of missing files.
WriteLine NextLine to CheckFile
end
' No files missing.
Put 2 into InstallError
End
End ' While Not EOF
End ' If DiskStatus
End ' If BothReady is 0
End ' If BothReady is 0
' Restore the hardware text cursor.
Use cursor
' Return all file resources to DOS.
CloseAllFiles
End ' Sub Copyfiles.
'==================================================================
'
' SUB SayGoodBye
'
' 4. SIGN OFF
' Replace the message in this routine with your own, or rewrite
' it completely.
'
' What it does:
' Displays a sign-off message.
'
'
' Globals affected:
' INTEGER BoxWidth
' STRING Msg
'
' Other routines called:
' GetYN
'
'==================================================================
Sub SayGoodBye
' Put a white on on blue banner across the top.
Text White on Blue
' Draw a bar across the top.
Repeat 79
Say "▓";
End
' Thank the user.
say @ 1, 25 "Thank you for using The Builder"
End ' Sub SayGoodBye
'==================================================================
' SUB DoInstall
'
' What it does:
' Performs the actual installation, either full or minimal.
' Assumes the installation data file exists.
'
' Globals affected:
' INTEGER BothReady
' STRING DefFullFile, DiskStatus, InstName
'
' Other routines called:
' CheckDrives, CopyFiles, CreateDirectories, ErrMsg,
' GetAndConfirmParams
'
'==================================================================
Sub DoInstall
' Filename for the CopyFiles routine.
Copying:=1
if FullInstall == 1
InstName := DefFullFile
end else
InstName := DefMinFile
end
DiskStatus:=DiskReady SourceDrive
if DiskStatus<>0
If exist SourceDrive+":"+InstName DiskStatus:=1
end
If DiskStatus
GetAndConfirmParams
' Make sure the specified drives are acceptable.
CheckDrives
If BothReady <> 0
DiskStatus := 0
CreateDirectories
if DiskStatus <> 0
CopyFiles
end else
Msg := "Can't create the subdirectory " + Target
ErrMsg
end ' If DiskStatus
End ' If BothReady
end else
Msg := "Can't find the installation file " + InstName
ErrMsg
End ' If DiskStatus
Copying:=0
End ' Sub DoInstall
'==================================================================
' SUB MakeDir
'
' What it does:
' Responds to a "MAKE_TARGET_DIR" line. Expects that the next line
' will be a subdirectory name. If that subdirectory doesn't
' already exist, creates it and changes to that target directory.
' Reassigns TargetDir to that new directory.
'
' IMPORTANT NOTE: Assumes that this is one level down from the
' current target directory (which may have been created using
' a previous MAKE_TARGET_DIR). So if TargetDir is C:\BUILDER, and
' this line is EXAMPLES, the directory C:\BUILDER\EXAMPLES is
' created.
'
' Globals affected:
' INTEGER DiskStatus, NextLine
' STRING NextLine, TargetDir
'
' Other routines called:
' GetNextLine
'
'==================================================================
Sub MakeDir
' Get the next non-comment line from the disk and copy to the
' variable NextLine.
GetNextLine
' NextLine now has the subdir name to check for and create (if necessary).
' See if it already exists. DiskStatus will be 1 if it does.
DiskStatus := DirExists NextLine
If DiskStatus is 0
' Doesn't exist. Change to it and create it.
' Change to the target directory. (Actually, we should already be there.)
System "CD " + TargetDrive + TargetDir
' Create it.
Msg := "About to: " + "MD " + TargetDrive + TargetDir + "\" + NextLine + ", press return."
ShowMsgBox
System "MD " + TargetDrive + TargetDir + "\" + NextLine
TargetDir := TargetDir + "\" + NextLine
end
' Change to the new directory.
System "CD " + TargetDrive + TargetDir
End ' Sub MakeDir
'==================================================================
' SUB ChangeDir
'
' What it does:
' Responds to a "CHANGE_TARGET_DIR" line. Expects that the next
' line will be a subdirectory name. Changes to that target
' directory, and reassigns TargetDir to that new directory.
'
' NOTE: Doesn't change the logged disk drive, and inserts the
' target drive spec before it.
'
' Globals affected:
' STRING NextLine, TargetDir
'
' Other routines called:
' GetNextLine
'
'==================================================================
Sub ChangeDir
' Get the next non-comment line from the disk and copy to the
' variable NextLine.
GetNextLine
' NextLine now has the subdir name to change to.
' Change to the target directory. (Actually, we should already be there.)
System "CD " + TargetDrive + NextLine
' Make this the new target directory.
TargetDir := NextLine
End ' Sub ChangeDir
'==================================================================
' SUB RedrawMsgArea
'
' What it does:
' Writes over the message window in the current screen color
' and regenerates the title, so that the display looks as it
' did before the message window was drawn.
'
' Globals affected:
' INTEGER BoxWidth
' STRING ScreenWidth
'
' Other routines called:
' None
'
'==================================================================
SUB RedrawMsgArea
' Redraw over the box.
if ScreenType is "Mono"
Double Box 2, 2, BoxWidth, 7 Black on Black
end else
Double Box 2, 2, BoxWidth, 7 Blue on Blue
end
' Display a banner.
Text white on Blue
Say @ 2, 23 "<bold>Builder 1.50 installation program"
if Copying==0
Say @ 20, 10 "Press <bold><reverse><normal> and <bold><reverse><normal> ";
Say "to move the cursor and press {Enter} to select.";
end
End ' SUB RedrawMsgArea
'==================================================================
' SUB Extraction
'
' What it does:
' Responds to a "RUN_EXTRACTION" line. Expects that the next lines
' will be a filename, directory then a prompt. Displays the prompt,
' then extracts the filename.
'
' Globals affected:
' STRING Msg, NextLine, Scratch1, Correctlabel
'
' Other routines called:
' GetNextLine
'
'==================================================================
Sub Extraction
' Get the next non-comment line from the disk and copy to the
' variable NextLine.
GetNextLine
' This is the filename to extract.
CorrectLabel := NextLine
' Get the next non-comment line from the disk and copy to the
' variable DiskPrompt.
GetNextLine
'This is the directory to extract to.
scratch1:=NextLine
GetNextLine
' This is the prompt to display.
MSG := NextLine
'This commandline will extract the Lharc selfextracting archive
System SourceDrive+CorrectLabel+" /e"+Target+Scratch1+" >nul"
End ' Sub Extraction