home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
cmd_.zip
/
$.CMD
next >
Wrap
OS/2 REXX Batch file
|
1993-03-12
|
69KB
|
2,129 lines
/**
*** ╔════════════════════════════════════════════════════════════════════╗
*** ║ ║
*** ║ $.CMD - version 2.05 ║
*** ║ ║
*** ║ ────────────────────────────────────────────────────────────────── ║
*** ║ ║
*** ║ This is a collection of small execs put into one place to keep the ║
*** ║ directory clutter down a little bit. It also allows for local- ║
*** ║ ization of global variables and the reuse of general purpose ║
*** ║ routines. ║
*** ║ ║
*** ║ Many of the routines listed here are intended to be run while ║
*** ║ there is no other activities on the machine. As such, these ║
*** ║ routines also serve as a free suppliment to the product Chron ║
*** ║ currently marketed by Hilbert Computing. ║
*** ║ ║
*** ║ This can also serve as a working example of several REXX program- ║
*** ║ ming techniques. ║
*** ║ ║
*** ║ ────────────────────────────────────────────────────────────────── ║
*** ║ ║
*** ║ This code is provided on an as-is basis. There is no warranty ║
*** ║ expressed or implied in the code. There is no official support ║
*** ║ for this code. However, you are welcome to contact Hilbert ║
*** ║ Computing for questions or comments on the code. If you make your ║
*** ║ own changes to the code and wish to upload the modified code to ║
*** ║ a public forum, please note your modifications to the code. ║
*** ║ ║
*** ║ Many of the routines require the REXX suppliment DLLs found in ║
*** ║ OS/2 v2.0 and later. ║
*** ║ ║
*** ║ I can be reached at: ║
*** ║ ║
*** ║ Gary Murphy, Sr. Programmer ║
*** ║ Hilbert Computing ║
*** ║ 1022 N. Cooper ║
*** ║ Olathe, KS 66061 ║
*** ║ ║
*** ║ BBS...... (913) 829-2450 8N1 9600 ║
*** ║ CIS...... [73457,365] ║
*** ║ Prodigy.. VWSD07A ║
*** ║ ║
*** ║ ────────────────────────────────────────────────────────────────── ║
*** ║ ║
*** ║ Copyright (c) 1992, 1993 Hilbert Computing ║
*** ║ ║
*** ╚════════════════════════════════════════════════════════════════════╝
**/
/* Global variables */
machine = value("MACHINE", , "OS2ENVIRONMENT")
parse upper var machine machine .
select
when machine = '8590-0H9' then
do
Dir. = ''
Dir.Awk = 'd:\awk' /* AWK code */
Dir.Backup = 'd:\backup' /* Backups of critical files */
Dir.BC = 'n/a' /* Borland C++ for OS/2 */
Dir.BCSource = 'n/a' /* Source code for B C++ programs */
Dir.BCToolkit = 'n/a' /* Borland include files */
Dir.Boot = 'c:\' /* Root of the boot drive */
Dir.CommPass = 'n/a' /* Directory for Golden CommPass(tm) */
Dir.IBMC = 'd:\ibmc' /* IBM C Set/2 */
Dir.IBMCSource = 'd:\ibmc\source' /* Source code for IBM C programs */
Dir.IBMCPP = 'd:\ibmcpp' /* IBM C Set/2 */
Dir.IBMCPPSource = 'd:\ibmc\source' /* Source code for IBM C programs */
Dir.IBMWF = 'd:\ibmwf' /* IBM WorkFrame/2 */
Dir.Maximus = 'n/a' /* Maximus BBS code. */
Dir.MSC = 'd:\msc' /* Microsoft C 6.0 */
Dir.MSCSource = 'd:\msc\source' /* Source code for MS C programs */
Dir.ProdCmd = 'd:\products\cmd' /* Shareware command files */
Dir.ProdDat = 'd:\products\data' /* Shareware data files */
Dir.ProdDll = 'd:\products\dll' /* Shareware datalink libraries */
Dir.Products = 'd:\products' /* Shareware executable directory */
Dir.Rexx = 'd:\rexx' /* REXX code and Kedit macros */
Dir.Server = 'm:\os2nfs\backup' /* Directory for server backup */
Dir.SprintMail = 'd:\sprmail' /* Directory for SprintMail */
Dir.Temp = 'd:\temp' /* Temporary work directory */
Dir.Toolkit13 = 'd:\toolkt13' /* IBM Tools and Info for OS/2 v1.3 */
Dir.Toolkit20 = 'd:\toolkt20' /* IBM Tools and Info for OS/2 v2.0 */
Dir.Unix = 'd:\unix' /* UNIX ports from GNU */
Dir.VDisk = 'e:\' /* Virtual disk */
end
when machine = 'HILBERT' then
do
Dir. = ''
Dir.Awk = 'd:\awk' /* AWK code */
Dir.Backup = 'd:\backup' /* Backups of critical files */
Dir.BC = 'd:\bc' /* Borland C++ for OS/2 */
Dir.BCSource = 'd:\bc\source' /* Source code for B C++ programs */
Dir.BCToolkit = 'd:\topaz' /* Borland include files */
Dir.Boot = 'c:\' /* Root of the boot drive */
Dir.CommPass = 'd:\commpass' /* Directory for Golden CommPass(tm) */
Dir.IBMC = 'd:\ibmc' /* IBM C Set/2 */
Dir.IBMCSource = 'd:\ibmc\source' /* Source code for IBM C programs */
Dir.IBMCPP = 'd:\ibmcpp' /* IBM C Set/2 */
Dir.IBMCPPSource = 'd:\ibmc\source' /* Source code for IBM C programs */
Dir.IBMWF = 'd:\ibmwf' /* IBM WorkFrame/2 */
Dir.Maximus = 'd:\maximus' /* Maximus BBS code. */
Dir.MSC = 'd:\msc' /* Microsoft C 6.0 */
Dir.MSCSource = 'd:\msc\source' /* Source code for MS C programs */
Dir.ProdCmd = 'd:\products\cmd' /* Shareware command files */
Dir.ProdDat = 'd:\products\data' /* Shareware data files */
Dir.ProdDll = 'd:\products\dll' /* Shareware datalink libraries */
Dir.Products = 'd:\products' /* Shareware executable directory */
Dir.Rexx = 'd:\rexx' /* REXX code and Kedit macros */
Dir.Server = 'n/a' /* Directory for server backup */
Dir.SprintMail = 'n/a' /* Directory for SprintMail */
Dir.Temp = 'd:\temp' /* Temporary work directory */
Dir.Toolkit13 = 'd:\toolkt13' /* IBM Tools and Info for OS/2 v1.3 */
Dir.Toolkit20 = 'd:\toolkt20' /* IBM Tools and Info for OS/2 v2.0 */
Dir.Unix = 'd:\unix' /* UNIX ports from GNU */
Dir.VDisk = 'g:\' /* Virtual disk */
end
when machine = 'LPAR' then
do
Dir. = ''
Dir.Awk = 'd:\awk' /* AWK code */
Dir.Backup = 'd:\backup' /* Backups of critical files */
Dir.BC = 'd:\bc' /* Borland C++ for OS/2 */
Dir.BCSource = 'd:\bc\source' /* Source code for B C++ programs */
Dir.BCToolkit = 'd:\topaz' /* Borland include files */
Dir.Boot = 'c:\' /* Root of the boot drive */
Dir.CommPass = 'd:\commpass' /* Directory for Golden CommPass(tm) */
Dir.IBMC = 'd:\ibmc' /* IBM C Set/2 */
Dir.IBMCSource = 'd:\ibmc\source' /* Source code for IBM C programs */
Dir.IBMCPP = 'd:\ibmcpp' /* IBM C Set/2 */
Dir.IBMCPPSource = 'd:\ibmc\source' /* Source code for IBM C programs */
Dir.IBMWF = 'd:\ibmwf' /* IBM WorkFrame/2 */
Dir.Maximus = 'd:\maximus' /* Maximus BBS code. */
Dir.MSC = 'd:\msc' /* Microsoft C 6.0 */
Dir.MSCSource = 'd:\msc\source' /* Source code for MS C programs */
Dir.ProdCmd = 'd:\products\cmd' /* Shareware command files */
Dir.ProdDat = 'd:\products\data' /* Shareware data files */
Dir.ProdDll = 'd:\products\dll' /* Shareware datalink libraries */
Dir.Products = 'd:\products' /* Shareware executable directory */
Dir.Rexx = 'd:\rexx' /* REXX code and Kedit macros */
Dir.Server = 'n/a' /* Directory for server backup */
Dir.SprintMail = 'n/a' /* Directory for SprintMail */
Dir.Temp = 'd:\temp' /* Temporary work directory */
Dir.Toolkit13 = 'd:\toolkt13' /* IBM Tools and Info for OS/2 v1.3 */
Dir.Toolkit20 = 'd:\toolkt20' /* IBM Tools and Info for OS/2 v2.0 */
Dir.Unix = 'd:\unix' /* UNIX ports from GNU */
Dir.VDisk = 'g:\' /* Virtual disk */
end
otherwise
do
say 'Your MACHINE environment variable is not set or is not recognized.'
exit
end
end /* select */
File. = ''
File.Max.Log = 'maxaccum.log'
File.BBS = 'files.bbs'
File.Temp.1 = Dir.Temp'\temp.1'
File.Temp.2 = Dir.Temp'\temp.2'
File.Temp.3 = Dir.Temp'\temp.3'
File.Temp.ChkDsk = Dir.Temp'\chkdsk.out'
File.Temp.Space = Dir.Temp'\space.out'
File.Temp.Changed = Dir.Temp'\changed.out'
File.Temp.Maxdl = Dir.Temp'\maxdl.out'
File.Temp.Offsite = Dir.Temp'\offsite.out'
Pgm. = ''
Pgm.Zip = Dir.Unix'\zip.exe'
Pgm.UnZip = Dir.Unix'\unzip.exe'
Pgm.Grep = Dir.Unix'\grep.exe'
Pgm.Editor = Dir.Products'\kedit.exe'
Pgm.CalcCrc = Dir.Products'\calccrc.exe'
Pgm.Awk = Dir.Unix'\gawk.exe'
Pgm.Tail = Dir.Unix'\tail.exe'
Pgm.Notify = Dir.Products'\pmmessag.exe'
Grep. = ''
Grep.Options = ''
Grep.Re.LogKeep = '"^[\+\=]"'
Grep.Re.LogCall = '"^\+.*calling ("'
Upm. = ''
Upm.Userid = 'Hilbert'
Upm.Password = ''
/* Load the REXX DLL entry points */
call LoadFunctions
/* Parse the command */
parse arg cmd parms
parse upper var cmd cmd
/* Save the current directory */
Dir.Current = directory()
select
when abbrev('BACKUP' ,cmd, 3) then call Backup parms
when abbrev('BKUP' ,cmd, 2) then call Backup parms
when abbrev('CHANGED' ,cmd, 3) then call Changed parms
when abbrev('CHECK' ,cmd, 3) then call Check parms
when abbrev('CHK' ,cmd, 3) then call Check parms
when abbrev('CK' ,cmd, 2) then call Check parms
when abbrev('COPY' ,cmd, 2) then call Copy parms
when abbrev('CRC' ,cmd, 2) then call CrcSum parms
when abbrev('ENVIRONMENT',cmd, 3) then call Environment parms
when abbrev('FIND' ,cmd, 2) then call WhereIs parms
when abbrev('INSTALL' ,cmd, 1) then call Install parms
when abbrev('LOADFUNC' ,cmd, 3) then call LoadFunctions parms
when abbrev('LOADSYSTEM' ,cmd, 3) then call LoadFunctions parms
when abbrev('MAXIMUS' ,cmd, 3) then call Maximus parms
when abbrev('MIGRATE' ,cmd, 3) then call Migrate parms
when abbrev('PROFILE' ,cmd, 2) then call Profile parms
when abbrev('SPACE' ,cmd, 2) then call Space parms
when abbrev('TEST' ,cmd, 2) then call Test parms
when abbrev('WHEREIS' ,cmd, 2) then call WhereIs parms
when abbrev('VDISKLOAD' ,cmd, 2) then call VDiskLoad parms
when abbrev('REXXUNPACK' ,cmd, 2) then call RexxUnpack parms
when abbrev('ZIP' ,cmd, 1) then call Zip parms
otherwise
say "Command '"cmd"' not recognized"
end /* Select */
/* Return to the starting directory */
Dir.Current = directory(Dir.Current)
exit
/**
*** ╔══════════════════════════════════════════════════════════════════════╗
*** ║ Command Processor Subroutines ║
*** ╚══════════════════════════════════════════════════════════════════════╝
**/
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Zip Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Zip: procedure expose Pgm.
/**
*** This will call a compression program to create a package in
*** the correct directory. It looks for a zip list file of with an
*** extension of ".ZPL"
**/
parse arg ZipFile .
/* If there wasn't a zip file passed, use the project environment */
/* for the name. */
if ZipFile = '' then
do
ZipFile = value("PROJECT", , "OS2ENVIRONMENT")
if ZipFile = '' then
do
say "Project environment variable not set."
return
end
call directory('archive')
end
'@'Pgm.Zip '-o@' ZipFile'.zip <' ZipFile'.zpl'
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Copy Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Copy: procedure expose Pgm.
/**
*** This will call a C routine to calculate the checksum and CRC
*** values for a file. It either stores the calculated values or compares
*** the calculated value to the stored value.
**/
parse arg Src Dest .
if Dest = '' then
Dest = "A:"
call SysFileTree Src, 'Source', 'F'
BytesCopied = 0
do i = 1 to Source.0
parse var Source.i . . BytesFile . FullSource
/* Extract just the file name */
PathEnd = lastpos('\',FullSource)
FullDest = Dest'\'substr(FullSource, (PathEnd+1))
Retries = 0
do until (CheckOk = 1) | (Retries >= 3)
'@copy' FullSource FullDest '> nul'
SrcCheckWord = CalculateCheckWord(FullSource)
DstCheckWord = CalculateCheckWord(FullDest)
if SrcCheckWord = DstCheckWord then
do
CheckOk = 1
say FullSource
end
else
do
CheckOk = 0
Retries = Retries + 1
say 'Copy for' FullSource 'failed verification. Retry #'Retries'.'
end
end /* do until */
if Retries >= 3 then
do
say "Too many failures. Aborting..."
return
end
BytesCopied = BytesCopied + BytesFile
end
say ' 'Source.0 'file(s) ['BytesCopied' bytes] copied.'
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ VDISK Load Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
VDiskLoad: procedure expose Dir.
/**
*** This will load the virtual disks with the files for the optimal
*** use of the RAM disk.
**/
parse arg cmd parms
parse upper var cmd cmd
select
when abbrev('IBMC' ,cmd, 3) then call VDiskLoadIBMC parms
otherwise
say "Subcommand (VDISKLOAD): '"cmd"' not recognized"
end /* Select */
return
VdiskLoadOptions: procedure expose VDiskOpt.
/**
*** This will parse the VDiskLoad parameters and return them in an
*** exposed stem variable.
**/
arg options
VDiskOpt. = ''
VDiskOpt.H = 1 /* Copy header files */
VDiskOpt.EXE = 1 /* Copy EXE files */
VDiskOpt.IPMD = 1 /* Copy debugger files */
VDiskOpt.CLEAR = 1 /* Delete everything on the RAM disk */
do i = 1 to words(options)
option = word(options, i)
parse upper var option option
select
when option = "H" then VDiskOpt.H = 1
when option = "NOH" then VDiskOpt.H = 0
when option = "EXE" then VDiskOpt.EXE = 1
when option = "NOEXE" then VDiskOpt.EXE = 0
when option = "DEBUG" then VDiskOpt.IPMD = 1
when option = "NODEBUG" then VDiskOpt.IPMD = 0
when option = "IPMD" then VDiskOpt.IPMD = 1
when option = "NOIPMD" then VDiskOpt.IPMD = 0
when option = "CLEAR" then VDiskOpt.CLEAR = 1
when option = "DELETE" then VDiskOpt.CLEAR = 1
when option = "REMOVE" then VDiskOpt.CLEAR = 1
when option = "APPEND" then VDiskOpt.CLEAR = 0
when option = "ALL" then
do
VDiskOpt.IPMD = 1
VDiskOpt.EXE = 1
VDiskOpt.H = 1
end
when option = "NONE" then
do
VDiskOpt.IPMD = 0
VDiskOpt.EXE = 0
VDiskOpt.H = 0
end
otherwise
say "Warning: Unrecognized option" option". It was ignored"
end /* select */
end
return
VDiskLoadIBMC: procedure expose Dir.
/**
*** This loads the compiler, etc to the virtual disk
**/
parse arg parms
/* Clear out the stuff that is there already */
if "n/a" = Dir.VDisk then
return
call VDiskLoadOptions parms
if VDiskOpt.CLEAR then
"@rm" Dir.VDisk"*"
/* Copy the files */
if VDiskOpt.EXE then
do
"@xcopy" Dir.IBMC"\bin\dd*.exe" Dir.VDisk
"@xcopy" Dir.IBMC"\bin\icc*.exe" Dir.VDisk
end
if VDiskOpt.H then
do
"@xcopy" Dir.Toolkit20"\c\os2h\pm*.h" Dir.VDisk
"@xcopy" Dir.Toolkit20"\c\os2h\bse*.h" Dir.VDisk
end
if VDiskOpt.IPMD then
do
"@xcopy d:\ipmd3aw\ipmd*.exe" Dir.VDisk
end
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ CRC and Checksum Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
CrcSum: procedure
/**
*** This will call a C routine to calculate the checksum and CRC
*** values for a file. It either stores the calculated values or compares
*** the calculated value to the stored value.
**/
parse arg cmd parms
parse upper var cmd cmd
select
when abbrev('ADD' ,cmd, 1) then call CrcSumAdd parms
when abbrev('QUERY' ,cmd, 1) then call CrcSumQuery parms
when abbrev('GET' ,cmd, 1) then call CrcSumQuery parms
when abbrev('CHECK' ,cmd, 1) then call CrcSumCheck parms
otherwise
say "Subcommand (PROFILE): '"cmd"' not recognized"
end /* Select */
return
CrcSumQuery: procedure Expose Pgm.
/**
*** This will display the calculated CRC and Checksum to the extended
*** attributes
**/
arg file options
RCode = SysGetEA(file, "Checkword", "CheckWord")
if RCode = 0 then
do
if CheckWord = '' then
say "The check word for" file "doesn't exist."
else
say "The check word for" file "is" CheckWord"."
end
else
say "Return code" RCode "from EA query."
return CheckWord
CrcSumAdd: procedure expose Pgm.
/**
*** This will add the calculated CRC and Checksum to the extended
*** attributes
**/
arg file options
CheckWord = CalculateCheckWork(file)
call SysPutEA file, 'CheckWord', Checkword
return
CrcSumCheck: procedure expose Pgm.
/**
*** This will compare the calculated CRC and Checksum to the extended
*** attributes
**/
arg file options
CheckWordCalc = CalculateCheckWord(file)
call SysGetEA file, "Checkword", "CheckWordEA"
if CheckWordCalc <> CheckWordEA then
if CheckWordEA = "" then
say "File" file "has a check word mismatch because there was no stored EA."
else
say "File" file "has a check word mismatch."
return
CalculateCheckWord: procedure expose Pgm.
/**
*** This will calculate the check word for the file passed.
**/
arg file .
'@'Pgm.CalcCrc file '| rxqueue'
if rc <> 0 then
do
do i = 1 to queued()
parse pull msg
say msg
end
return "0000:0000"
end
pull . Crc . Sum
return right(Crc,4,'0')':'right(Sum,4,'0')
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Migrate Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Migrate: procedure expose File. Dir.
/**
*** This will move the file from the working directory to the production
*** directory based on the file name if passed. If the filename is not
*** passed, it will migrate by the current directory and the project
*** environment variable
**/
arg FileSpec
if FileSpec = '' then
call MigrateByDir
else
call MigrateByExt FileSpec
return
MigrateByDir: procedure expose File. Dir.
/**
*** This will migrate the file from the development directory to the
*** production directory based on the current path and the project
*** variable.
**/
Project = value("PROJECT", , "OS2ENVIRONMENT")
if Project = '' then
do
say "Project environment variable not set."
return
end
Current = UpperCase(directory())
select
when Current = UpperCase(Dir.Rexx) then Ext = 'CMD'
when Current = UpperCase(Dir.IBMCSource) then Ext = 'EXE'
when Current = UpperCase(Dir.MSCSource) then Ext = 'EXE'
otherwise Ext = ''
end /* select */
call MigrateByExt Project'.'Ext
return
MigrateByExt: procedure expose File. Dir.
/**
*** This will migrate the file from the development directory to the
*** production directory based on the file extension.
**/
arg FileSpec
if verify(FileSpec, '\*?:', 'Match') > 0 then
do
say "The file must be specified with no wildcard or path information."
return
end
parse var FileSpec FileName '.' FileExt
select
when FileExt = 'DLL' then Target = Dir.ProdDll
when FileExt = 'CMD' then Target = Dir.ProdCmd
when FileExt = 'EXE' then Target = Dir.Products
otherwise
do
say "Unrecognized extension:" FileExt". No action taken."
return
end
end /* select */
'copy' FileSpec Target
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Space Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
RexxUnpack: procedure expose File. Pgm.
/**
*** This will recurse through all the specified drives and generate
*** a disk utilization report on the space used by directory.
**/
arg RexxSource .
/* Open the REXX source file. If not found, try appending a CMD on the end */
if (\Exists(RexxSource)) then
do
RexxSource = RexxSource'.CMD'
if (\Exists(RexxSource)) then
do
say 'Error: Input file "'RexxSource'" doesn''t exist.'
return
end
end
RexxSource = Open(RexxSource 'READ')
Indent = 0
do while(lines(RexxSource) > 0)
SourceLine= linein(RexxSource)
/* Keep breaking the line into semicolon-delimited lines until there */
/* are no more. */
do until SourceLine = ''
parse var SourceLine FirstStmt ';' SourceLine
parse upper var FirstStmt Keyword .
/* Look for statements that will indent a block */
select
when Keyword = 'DO' then Indent = Indent + 3
when Keyword = 'SELECT' then Indent = Indent + 3
otherwise
nop
end /* select */
/* Display the line */
say copies(" ", max(0,Indent)) FirstStmt
/* Check for keywords that un-indent the block */
select
when Keyword = 'END' then Indent = Indent - 3
otherwise
nop
end /* select */
end
end /* while */
RexxSource = Close(RexxSource)
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Space Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Space: procedure expose File. Pgm.
/**
*** This will recurse through all the specified drives and generate
*** a disk utilization report on the space used by directory.
**/
arg DisplayLevel DriveList
Report. = ''
Report.0 = 0
/* Give defaults for missing parameters */
if DisplayLevel = '' then DisplayLevel = 32768
if DisplayLevel = '*' then DisplayLevel = 32768
if DisplayLevel = '.' then DisplayLevel = 32768
if DriveList = '' then DriveList = SysDriveMap('C:', 'LOCAL')
do i = 1 to words(DriveList)
Drive = word(DriveList, i)
BytesDrive = SpaceDirectory(Drive'\*.*', 0, DisplayLevel)
end
/* Erase the old and open a new file */
'@erase' File.Temp.Space '> nul'
ReportFile = Open(File.Temp.Space 'WRITE')
/* Write the headers */
call lineout ReportFile, center("File", 10) center("w/ Child", 12) center("Directory", 54)
call lineout ReportFile, copies('-', 10) copies("-", 12) copies("-", 54)
/* Write the space utilization report */
do i = Report.0 to 1 by -1
call lineout ReportFile, Report.i
end
ReportFile = Close(ReportFile)
/* Start the editor on the report file */
''Pgm.Editor File.Temp.Space
return
SpaceDirectory: procedure expose File. Report. Pgm.
/**
*** This will generate a space utilization report for a given drive
**/
arg Directory, Level, DisplayLevel
/* Sum the size of all files in this directory */
call SysFileTree Directory, 'Current', 'F'
BytesDir = 0
do i = 1 to Current.0
parse var Current.i . . BytesFile . FileName
BytesDir = BytesDir + BytesFile
end
/* Determine the size of all the files in all the subtrees under this */
/* directory. */
call SysFileTree Directory, 'Current', 'D'
BytesChildren = 0
do i = 1 to Current.0
parse var Current.i . . BytesFile . SubDirName
SubDirName = strip(SubDirName, 'Both')
BytesChildren = BytesChildren + SpaceDirectory(SubDirName'\*.*', (Level+1), DisplayLevel)
end
/* Generate the statistics for this directory and its descendants */
BytesSum = BytesDir + BytesChildren
if DisplayLevel >= Level then
do
/* Format the line for column output and add to the report */
BytesDirFmt = FormatComma(BytesDir)
BytesSumFmt = FormatComma(BytesSum)
Report.0 = Report.0 + 1
q = Report.0
Report.q = right(BytesDirFmt, 10) right(BytesSumFmt, 12) copies(" ", Level*3) Directory
end
return BytesSum
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Changed Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Changed: procedure expose File. Pgm.
/**
*** This will recurse through all the specified drives and generate
*** a byte count on the files with the archive bit on
**/
arg DisplayLevel DriveList
Report. = ''
Report.0 = 0
/* Give defaults for missing parameters */
if DisplayLevel = '' then DisplayLevel = 32768
if DisplayLevel = '*' then DisplayLevel = 32768
if DisplayLevel = '.' then DisplayLevel = 32768
if DriveList = '' then DriveList = SysDriveMap('C:', 'LOCAL')
do i = 1 to words(DriveList)
Drive = word(DriveList, i)
BytesDrive = ChangedDirectory(Drive'\*.*', 0, DisplayLevel)
end
/* Erase the old and open a new file */
'@erase' File.Temp.Changed '> nul'
ReportFile = Open(File.Temp.Changed 'WRITE')
/* Write the headers */
call lineout ReportFile, center("File", 10) center("w/ Child", 12) center("Directory", 54)
call lineout ReportFile, copies('-', 10) copies("-", 12) copies("-", 54)
/* Write the space utilization report */
do i = Report.0 to 1 by -1
call lineout ReportFile, Report.i
end
ReportFile = Close(ReportFile)
/* Start the editor on the report file */
''Pgm.Editor File.Temp.Changed
return
ChangedDirectory: procedure expose File. Report. Pgm.
/**
*** This will generate a changed files report for a given drive
**/
arg Directory, Level, DisplayLevel
/* Sum the size of all files in this directory */
call SysFileTree Directory, 'Current', 'F', '+****'
BytesDir = 0
Detail. = ''
Detail.0 = 0
do i = 1 to Current.0
parse var Current.i . . BytesFile . FileName
FileName = strip(FileName, 'Both')
BytesDir = BytesDir + BytesFile
if DisplayLevel = 0 then
do
Detail.0 = Detail.0 + 1
q = Detail.0
Detail.q = copies(" ", 25+Level*3) FileName
end
end
/* Determine the size of all the files in all the subtrees under this */
/* directory. */
call SysFileTree Directory, 'Current', 'D'
BytesChildren = 0
do i = 1 to Current.0
parse var Current.i . . BytesFile . SubDirName
SubDirName = strip(SubDirName, 'Both')
BytesChildren = BytesChildren + ChangedDirectory(SubDirName'\*.*', (Level+1), DisplayLevel)
end
/* Generate the statistics for this directory and its descendants */
BytesSum = BytesDir + BytesChildren
if (DisplayLevel = 0) | (DisplayLevel >= Level) then
do
if DisplayLevel = 0 then
do i = 1 to Detail.0
Report.0 = Report.0 + 1
q = Report.0
Report.q = Detail.i
end
/* Format the line for column output and add to the report */
BytesDirFmt = FormatComma(BytesDir)
BytesSumFmt = FormatComma(BytesSum)
Report.0 = Report.0 + 1
q = Report.0
Report.q = right(BytesDirFmt, 10) right(BytesSumFmt, 12) copies(" ", Level*3) Directory
end
return BytesSum
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Environment Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Environment: procedure expose Dir.
/**
*** This will list the contents of the environment variable in a list.
*** It was designed to list those environment variables that are a
*** list of directories, separated by semicolons, such as a PATH or
*** DPATH variable. Although it is not an environment variable, this
*** code will do the same for the LIBPATH by looking in the CONFIG.SYS
**/
arg EnvVariable .
/* Take care of the special case for LIBPATH */
if EnvVariable = 'LIBPATH' then
do
call SysFileSearch 'LIBPATH=', Dir.Boot'CONFIG.SYS', 'Libpath'
if Libpath.0 \= 1 then
do
say "Warning. Possibly more than 1 LIBPATH in CONFIG.SYS"
return
end
EnvValue = substr(Libpath.1, 9) /* Remove the "LIBPATH=" */
end /* if */
else
EnvValue = value(EnvVariable, , "OS2ENVIRONMENT")
/* Create the list of directories and display them in a nicely formatted */
/* list. */
Count = PathSplit(EnvValue) /* Set DirList. */
say "The following" Count "directories were found in the" EnvVariable
say copies("─",78)
do i = 1 to DirList.0
say " " DirList.i
end
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Install Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Install: procedure expose Pgm. Dir. File.
/**
*** This will install various packages into the correct directories from
*** a ZIP file.
**/
parse arg cmd parms
parse upper var cmd cmd
select
when abbrev('KEDKIT',cmd, 3) then call InstallKedKit parms
when abbrev('KEDIT' ,cmd, 3) then call InstallKedKit parms
otherwise
say "Subcommand (INSTALL): '"cmd"' not recognized"
end /* Select */
return
InstallKedKit: procedure expose Pgm. Dir. File.
/**
*** This will install the Kedit programming kit in the correct directories
*** on the disk.
**/
arg From .
if From = '' then
From = 'a:'
'@'Pgm.UnZip '-o' From'\kedkit.zip' Dir.Temp '| rxqueue'
do i = 1 to queued() until leader = 'SEARCHING'
pull leader .
end
do i = 1 to queued()
parse pull . FileName .
FileName = translate(FileName, '\', '/')
call InstallKedKitFile(FileName)
end
return
InstallKedKitFile: procedure expose Dir.
/**
*** This will copy the file passed to the appropriate directory and
*** remove it from the temp directory.
**/
arg FullFile .
PathEnd = lastpos('\', FullFile)
File = substr(FullFile, (PathEnd+1))
select
when File = "NMAKE386.INC" then DestDir = Dir.IBMCSource
when File = "PROFILE.KEX" then DestDir = Dir.Products
when File = "PROFILE.KML" then DestDir = Dir.ProdCmd
when File = "MMAKE.CMD" then DestDir = Dir.ProdCmd
when File = "X.CMD" then DestDir = Dir.ProdCmd
when File = "$.CMD" then DestDir = Dir.ProdCmd
when File = "BOX.KEX" then DestDir = Dir.ProdCmd
when File = "BOXNUM.KEX" then DestDir = Dir.ProdCmd
when File = "BOXSYM.KEX" then DestDir = Dir.ProdCmd
when File = "OSPORT.KEX" then DestDir = Dir.ProdCmd
when File = "SHTOLONG.KEX" then DestDir = Dir.ProdCmd
when File = "RINGLIST.KEX" then DestDir = Dir.ProdCmd
when File = "SPECSYM.KEX" then DestDir = Dir.ProdCmd
otherwise
do
say 'File' file 'not recognized. It is left in' Dir.Temp
return
end
end /* select */
say 'Copying:' FullFile DestDir
'@copy' FullFile DestDir '> nul'
'@del' FullFile '> nul'
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Profile Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Profile: procedure expose Pgm. Grep. Dir. File.
/**
*** The PROFILE command will configure an OS/2 command prompt session
**/
parse arg cmd parms
parse upper var cmd cmd
/* Change the number of lines on the screen */
'@mode co80,34'
select
when abbrev('REXX' ,cmd, 2) then call ProfileRexx parms
when abbrev('MSFTC' ,cmd, 2) then call ProfileMS parms
when abbrev('MSC' ,cmd, 2) then call ProfileMS parms
when abbrev('IBMCPP' ,cmd, 5) then call ProfileIBMCPP parms
when abbrev('IBMC' ,cmd, 3) then call ProfileIBM parms
when abbrev('CPP' ,cmd, 5) then call ProfileIBMCPP parms
when abbrev('CMD' ,cmd, 2) then call ProfileRexx parms
when abbrev('BORLAND',cmd, 3) then call ProfileBorland parms
when abbrev('BCC' ,cmd, 3) then call ProfileBorland parms
when abbrev('AWK' ,cmd, 1) then call ProfileAWK parms
otherwise
say "Subcommand (PROFILE): '"cmd"' not recognized"
end /* Select */
return
ProfileIBM: procedure expose Pgm. Grep. File. Dir.
/**
*** This will configure an OS/2 session for using the IBM C/Set 2
*** compiler
**/
parse arg project
'@echo off'
Dir.Current = directory(Dir.IBMCSource)
call SysCls
say "Setting project ...."
Env = value("PROJECT", project, "OS2ENVIRONMENT")
Env = value("PCALLX", project".c" , "OS2ENVIRONMENT")
Env = value("INCLUDE", Dir.Toolkit20"\c\os2h;"Dir.IBMC"\include", "OS2ENVIRONMENT")
Env = value("INCLUDETOOLS", Dir.Toolkit20"\c\os2h", "OS2ENVIRONMENT")
Env = value("INCLUDEC", Dir.IBMC"\include", "OS2ENVIRONMENT")
Env = value("LIB", Dir.Toolkit20"\os2lib;"Dir.IBMC"\lib" , "OS2ENVIRONMENT")
Env = value("IPFC", Dir.Toolkit20"\ipfc" , "OS2ENVIRONMENT")
EnvPath = value("PATH", , "OS2ENVIRONMENT")
Count = PathSplit(EnvPath) /* Set DirList. */
/* Remove all references to all compilers and toolkits */
Count = PathRemove(Dir.IBMC)
Count = PathRemove(Dir.IBMWF)
Count = PathRemove(Dir.Toolkit20)
Count = PathRemove(Dir.Toolkit13)
Count = PathRemove(Dir.MSC)
/* Re-build the path with the executables for the compilers and toolkits */
/* that we want for this session. */
EnvPath = PathBuild()
EnvPath = value("PATH", Dir.VDisk";"Dir.IBMC"\bin;"Dir.IBMWF"\bin;"Dir.Toolkit20"\os2bin;"EnvPath, "OS2ENVIRONMENT")
/* Do the same to the HELP environment variable */
EnvHelp = value("HELP", , "OS2ENVIRONMENT")
Count = PathSplit(EnvHelp) /* Set DirList. */
Count = PathRemove(Dir.Toolkit20)
Count = PathRemove(Dir.Toolkit13)
Count = PathRemove(Dir.MSC)
EnvHelp = PathBuild()
EnvHelp = value("HELP", Dir.IBMWF"\help;"Dir.Toolkit20"\os2help;"EnvHelp, "OS2ENVIRONMENT")
/* Do the same to the BOOKSHELF environment variable */
EnvBook = value("BOOKSHELF", , "OS2ENVIRONMENT")
Count = PathSplit(EnvBook) /* Set DirList. */
Count = PathRemove(Dir.Toolkit20)
Count = PathRemove(Dir.Toolkit13)
Count = PathRemove(Dir.MSC)
EnvBook = PathBuild()
EnvBook = value("BOOKSHELF", Dir.IBMC"\book;"Dir.Toolkit20"\book;"EnvBook, "OS2ENVIRONMENT")
return
ProfileIBMCPP: procedure expose Pgm. Grep. File. Dir.
/**
*** This will configure an OS/2 session for using the IBM C++/Set 2
*** compiler
**/
parse arg project
'@echo off'
Dir.Current = directory(Dir.IBMCPPSource)
call SysCls
say "Setting project ...."
Env = value("PROJECT", project, "OS2ENVIRONMENT")
Env = value("PCALLX", project".c" , "OS2ENVIRONMENT")
Env = value("INCLUDE", Dir.Toolkit20"\c\os2h;"Dir.IBMCPP"\include;"Dir.IBMCPP"\ibmclass", "OS2ENVIRONMENT")
Env = value("INCLUDETOOLS", Dir.Toolkit20"\c\os2h", "OS2ENVIRONMENT")
Env = value("INCLUDEC", Dir.IBMCPP"\include;"Dir.IBMCPP"\ibmclass","OS2ENVIRONMENT")
Env = value("LIB", Dir.Toolkit20"\os2lib;"Dir.IBMCPP"\lib" , "OS2ENVIRONMENT")
Env = value("IPFC", Dir.Toolkit20"\ipfc" , "OS2ENVIRONMENT")
EnvPath = value("PATH", , "OS2ENVIRONMENT")
Count = PathSplit(EnvPath) /* Set DirList. */
/* Remove all references to all compilers and toolkits */
Count = PathRemove(Dir.IBMC)
Count = PathRemove(Dir.IBMWF)
Count = PathRemove(Dir.Toolkit20)
Count = PathRemove(Dir.Toolkit13)
Count = PathRemove(Dir.MSC)
/* Re-build the path with the executables for the compilers and toolkits */
/* that we want for this session. */
EnvPath = PathBuild()
EnvPath = value("PATH", Dir.IBMCPP"\bin;"Dir.IBMWF"\bin;"Dir.Toolkit20"\os2bin;"EnvPath, "OS2ENVIRONMENT")
/* Do the same to the HELP environment variable */
EnvHelp = value("HELP", , "OS2ENVIRONMENT")
Count = PathSplit(EnvHelp) /* Set DirList. */
Count = PathRemove(Dir.Toolkit20)
Count = PathRemove(Dir.Toolkit13)
Count = PathRemove(Dir.MSC)
EnvHelp = PathBuild()
EnvHelp = value("HELP", Dir.IBMWF"\help;"Dir.Toolkit20"\os2help;"EnvHelp, "OS2ENVIRONMENT")
return
ProfileBorland: procedure expose Pgm. Grep. File. Dir.
/**
*** This will configure an OS/2 session for using the Borland C++ for OS/2
*** compiler
**/
parse arg project
'@echo off'
Dir.Current = directory(Dir.BCSource)
call SysCls
say "Setting project ...."
Env = value("PROJECT", project, "OS2ENVIRONMENT")
Env = value("PCALLX", project".c" , "OS2ENVIRONMENT")
Env = value("INCLUDE", Dir.BCToolkit"\include","OS2ENVIRONMENT")
Env = value("INCLUDETOOLS", Dir.BCToolkit"\include","OS2ENVIRONMENT")
Env = value("INCLUDEC", Dir.BCToolkit"\include","OS2ENVIRONMENT")
EnvPath = value("PATH", , "OS2ENVIRONMENT")
Count = PathSplit(EnvPath) /* Set DirList. */
/* Remove all references to all compilers and toolkits */
Count = PathRemove(Dir.IBMC)
Count = PathRemove(Dir.IBMWF)
Count = PathRemove(Dir.Toolkit20)
Count = PathRemove(Dir.Toolkit13)
Count = PathRemove(Dir.MSC)
/* Re-build the path with the executables for the compilers and toolkits */
/* that we want for this session. */
EnvPath = PathBuild()
EnvPath = value("PATH", Dir.BC"\bin;"Dir.Toolkit20"\os2bin;"EnvPath, "OS2ENVIRONMENT")
return
ProfileMS: procedure expose Pgm. Grep. File. Dir.
/**
*** This will configure an OS/2 session for using MSC and the OS/2 v1.3
*** Toolkit
**/
parse arg project
'@echo off'
Dir.Current = directory(Dir.MSCSource)
call SysCls
say "Setting project ...."
Env = value("PROJECT", project, "OS2ENVIRONMENT")
Env = value("PCALLX", project".c" , "OS2ENVIRONMENT")
Env = value("INCLUDE", Dir.Toolkit13"\c\include;"Dir.MSC"\include","OS2ENVIRONMENT")
Env = value("INCLUDETOOLS", Dir.Toolkit13"\c\include", "OS2ENVIRONMENT")
Env = value("INCLUDEC", Dir.MSC"\include", "OS2ENVIRONMENT")
Env = value("LIB", Dir.Toolkit13"\lib;"Dir.MSC"\lib" , "OS2ENVIRONMENT")
Env = value("IPFC", Dir.Toolkit13"\ipfc" , "OS2ENVIRONMENT")
EnvPath = value("PATH", , "OS2ENVIRONMENT")
Count = PathSplit(EnvPath) /* Set DirList. */
/* Remove all references to all compilers and toolkits */
Count = PathRemove(Dir.IBMC)
Count = PathRemove(Dir.IBMWF)
Count = PathRemove(Dir.Toolkit20)
Count = PathRemove(Dir.Toolkit13)
Count = PathRemove(Dir.MSC)
/* Re-build the path with the executables for the compilers and toolkits */
/* that we want for this session. */
EnvPath = PathBuild()
EnvPath = value("PATH", Dir.MSC"\bin;"Dir.Toolkit13"\bin;"EnvPath, "OS2ENVIRONMENT")
/* Do the same to the HELP environment variable */
EnvHelp = value("HELP", , "OS2ENVIRONMENT")
Count = PathSplit(EnvHelp) /* Set DirList. */
Count = PathRemove(Dir.Toolkit20)
Count = PathRemove(Dir.Toolkit13)
Count = PathRemove(Dir.MSC)
EnvHelp = PathBuild()
EnvHelp = value("HELP", Dir.Toolkit20"\os2help;"EnvHelp, "OS2ENVIRONMENT")
return
ProfileRexx: procedure expose Pgm. Grep. File. Dir.
/**
*** This will configure an OS/2 session for working with REXX
**/
parse arg project
'@echo off'
'prompt [$p]'
Dir.Current = directory(Dir.Rexx)
call SysCls
say "Setting project ...."
Env = value("PROJECT", project, "OS2ENVIRONMENT")
Env = value("PCALLX", project".cmd" , "OS2ENVIRONMENT")
return
ProfileAWK: procedure expose Pgm. Grep. File. Dir.
/**
*** This will configure an OS/2 session for AWK development
**/
parse arg project
'@echo off'
Dir.Current = directory(Dir.AWK)
call SysCls
say "Setting project ...."
Env = value("PROJECT", project, "OS2ENVIRONMENT")
Env = value("PCALLX", project".cmd" , "OS2ENVIRONMENT")
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Maximus Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Maximus: procedure expose Pgm. Grep. Dir. File.
parse arg cmd parms
parse upper var cmd cmd
select
when abbrev('CLEANLOG' ,cmd, 6) then call MaximusCleanLog parms
when abbrev('CLEANFILES',cmd, 6) then call MaximusCleanFiles parms
when abbrev('LOGONS' ,cmd, 3) then call MaximusLogons parms
when abbrev('TODAY' ,cmd, 3) then call MaximusToday parms
when abbrev('DOWNLOADS' ,cmd, 2) then call MaximusDownloads parms
when abbrev('DL' ,cmd, 2) then call MaximusDownloads parms
otherwise
say "Subcommand (MAXIMUS): '"cmd"' not recognized"
end /* Select */
return
MaximusCleanLog: procedure expose Pgm. Grep. File. Dir.
/**
*** This will trim the log for the Maximus BBS by keeping only those
*** lines that being with a '+' or '='. These are the logon, logoff
*** and download messages.
**/
'@echo off'
Dir.Maximus = directory(Dir.Maximus)
Pgm.Grep Grep.Options Grep.Re.LogKeep File.Max.Log '>' File.Temp.1
'copy' File.Temp.1 File.Max.Log
/* Clean up the temporary files */
'erase' File.Temp.1
return
MaximusCleanFiles: procedure expose Pgm. File. Dir.
/**
*** This will look for the files that are created by the Maximus BBS
*** when a path override is done by the sysop and a file is uploaded.
*** When those files are found, they are deleted.
**/
'erase' File.Temp.1
map = SysDriveMap('C:', 'USED')
i = 1
drive = word(map, i)
do while(drive \= '')
call SysFileTree drive'\'File.BBS, 'Found', 'FSO'
do j = 1 to Found.0
'erase' found.j
end
i = i + 1
drive = word(map, i)
end /* do */
return
MaximusLogons: procedure expose Pgm. Grep. File. Dir.
/**
***
**/
'@echo off'
Dir.Maximus = directory(Dir.Maximus)
Pgm.Grep Grep.Options Grep.Re.LogCall File.Max.Log
return
MaximusDownloads: procedure expose Pgm. File. Dir.
/**
***
**/
'@echo off'
Dir.Maximus = directory(Dir.Maximus)
Pgm.Awk '-f' Dir.Awk'\MaxDLByFile.awk' File.Max.Log '>' File.Temp.MaxDl
Pgm.Awk '-f' Dir.Awk'\MaxDL.awk' File.Max.Log '>>' File.Temp.MaxDl
Pgm.Editor File.Temp.MaxDl
return
MaximusToday: procedure expose Pgm. Grep. File. Dir.
/**
***
**/
'@echo off'
Dir.Maximus = directory(Dir.Maximus)
parse value date('N') with dd mmm .
dd = right(dd, 2, '0')
Pgm.Grep '"'dd mmm'"' File.Max.Log '|' Pgm.Awk '-f' Dir.Awk'\MaxToday.AWK'
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Backup Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Backup: procedure expose Dir. File. Upm.
parse arg cmd parms
parse upper var cmd cmd
select
when abbrev('FILE' ,cmd, 1) then call BackupFile parms
when abbrev('OFFSITE' ,cmd, 1) then call BackupOffsite parms
when abbrev('SERVER' ,cmd, 1) then call BackupOffsite parms
when abbrev('CHRON' ,cmd, 5) then call BackupChron parms
when abbrev('CONFIG' ,cmd, 4) then call BackupConfig parms
when abbrev('CISMSGS' ,cmd, 4) then call BackupCISMsgs parms
when abbrev('DATABASE',cmd, 2) then call BackupDatabase parms
when abbrev('DB' ,cmd, 2) then call BackupDatabase parms
otherwise
say "Subcommand (BACKUP): '"cmd"' not recognized"
end /* Select */
return
BackupDatabase: procedure expose Dir. File. Upm.
/**
*** This will backup the database passed on the command line.
**/
parse arg database password
'@startdbm'
/* If the password was passed on the command line, honor that. Next, */
/* check the Upm stem variable to see if there was a default password */
/* specified there. If not, let UPM prompt for it. */
if password = '' then
password = Upm.Password
if password = '' then
'@logon' Upm.Userid
else
'@logon' Upm.Userid '/P='password
call dbm 'BACKUP DATABASE' database 'ALL TO 0'
return
BackupCISMsgs: procedure expose Dir.
/**
*** This will backup the message base from CompuServe. The *.MSG files
*** are created by the (exceptional) Golden CommPass program from
*** Creative Systems, Inc.
**/
call SysFileTree Dir.Commpass'\*.MSG', 'Found', 'FT'
do i = 1 to Found.0
parse var Found.i FileName '.MSG' .
/* Copy the file to the backup directory */
FileExt = right(date("days"),3,"0") /* Julian date padded w/ 0's */
say 'copy' Found.0 Dir.Backup'\'FileName'.'FileExt /*«»*/
if rc = 0 then
say 'del' Found.0 /*«»*/
DeleteCount = DeleteOldFiles(Dir.Backup'\'Filename'.*', 3)
end /* do i = ... */
return
BackupConfig: procedure expose Dir.
/**
*** This will backup multiple generations of the CONFIG.SYS file. It
*** will only back it up if it has changed (i.e. the archive bit is on)
**/
BootDrive = strip(Dir.Boot, 'Trailing', '\')
call SysFileTree BootDrive'\CONFIG.SYS', 'Found', 'F', '+****', '-****'
if Found.0 then
do
FileExt = right(date("days"),3,"0") /* Julian date padded w/ 0's */
'copy' BootDrive'\CONFIG.SYS' Dir.Backup'\CONFIG.'FileExt
'@attrib -A' BootDrive'\CONFIG.SYS'
end
/* Keep the number of config backups to a reasonable number */
DeleteCount = DeleteOldFiles(Dir.Backup'\CONFIG.*', 8)
return;
BackupFile: procedure expose Dir.
/**
*** This will backup multiple generations of the file passed. It
*** will only back it up if it has changed (i.e. the archive bit is on)
**/
arg FileSpec Archives
if FileSpec = '' then
do
say "No file specified."
return
end
if Archives = '' then Archives = 12
if Archives < 1 then Archives = 1
call SysFileTree FileSpec, 'Found', 'F', '+****', '-****'
do i = 1 to Found.0
parse var Found.i . . . . FileSrc
FileExt = right(date("days"),3,"0") /* Julian date padded w/ 0's */
/* Pull out the file name */
psn = lastpos('\', FileSrc)
FileName = substr(FileSrc, (psn+1))
parse var FileName FileName '.' .
'@copy' FileSrc Dir.Backup'\'FileName'.'FileExt '> nul'
'@attrib -A' FileSrc
DeleteCount = DeleteOldFiles(Dir.Backup'\'FileName'.*', Archives)
end
say " " Found.0 "file(s) copied."
return;
BackupOffsite: procedure expose Dir. File.
/**
*** This will backup all of the files in the desired directories to the
*** server for offsite storage
**/
if (Dir.Server = 'n/a') then
do
say 'No backup server device specified'
return
end
/* Make sure the dest drive exists */
DriveList = SysDriveMap('C:')
DestDrive = left(Dir.Server, 2)
DestDrive = UpperCase(DestDrive)
if (wordpos(DestDrive, DriveList) = 0) then
do
say "Destination drive ("DestDrive") not available"
return
end
/* Delete the output file */
if exists(File.Temp.Offsite) then
"@erase" File.Temp.Offsite
/* Backup the following directories. If the dest directory doesn't */
/* exist, XCOPY will prompt with the "Drive or file" question. */
call BackupOffsiteDirectory("c:\awk \awk")
call BackupOffsiteDirectory("c:\aix \aix")
call BackupOffsiteDirectory("c:\products \products")
call BackupOffsiteDirectory("c:\ibmc\source \ibmc\source")
call BackupOffsiteDirectory("c:\doc\notes \doc\notes")
call BackupOffsiteDirectory("c:\doc\sprint \doc\sprint")
return
BackupChron: procedure expose Dir.
/**
*** This will backup the CHRON.DAT file. If this is a daily backup,
*** the file is created with an extension equal to the first three
*** letters of the day of the week. If this is a weekly backup, the
*** file is created with an extension of ".BKW". Otherwise, the
*** file is ".SAV"
**/
arg parms
select
when abbrev('DAILY' ,parms, 1) then
Destination = 'chron.'left(date('W'),3)
when abbrev('WEEKLY',parms, 1) then
Destination = 'chron.bkw'
otherwise
Destination = 'chron.sav'
end /* select */
Dir.ProdDat = directory(Dir.ProdDat)
'copy chron.dat' Dir.Backup'\'Destination
return;
BackupOffsiteDirectory: procedure expose Dir. File.
/**
*** This will backup the changed files to the server for offsite
*** secure storage.
**/
arg source dest .
'@echo Copying' source '──' Dir.Server || dest'... >>' File.Temp.Offsite
'@xcopy /E /M' source Dir.Server || dest '>>' File.Temp.Offsite
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Check Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Check: procedure expose Dir. File. Pgm.
parse arg cmd parms
parse upper var cmd cmd
select
when abbrev('DIRECTORY',cmd, 2) then call CheckDir parms
when abbrev('DRIVES' ,cmd, 2) then call CheckDrives parms
when abbrev('FLOPPY' ,cmd, 2) then call CheckFloppy parms
when abbrev('FILE' ,cmd, 1) then call CheckFile parms
when abbrev('SELF' ,cmd, 4) then call CheckSelf parms
when abbrev('MAIL' ,cmd, 1) then call CheckMail parms
otherwise
say "Subcommand (CHECK): '"cmd"' not recognized"
end /* Select */
return
CheckMail: procedure expose File. Pgm. Dir.
/**
*** This will see if there has been any new SprintMail loaded down. It
*** checks by looking for the archive bit on the files in the IN box.
*** This is intended to be run by CHRON.
**/
call SysFileTree Dir.SprintMail'\IN.BOX\*.ASC', 'Found', 'F', '+****', '-****'
if Found.0 then
do
'@start' Pgm.Notify 'You have new SprintMail'
'@attrib -A' Dir.SprintMail'\IN.BOX\*.ASC'
end
return
CheckDrives: procedure expose File. Pgm.
/**
*** This will run a CHKDSK on both the C: and D: drives and pipe the output
*** into a file. Once both have been run, KEDIT is started with the
*** output file to display the results. This is intended to be run by
*** CHRON.
**/
'@erase' File.Temp.ChkDsk
map = SysDriveMap('C:', 'LOCAL')
i = 1
drive = word(map, i)
do while(drive \= '')
say "Checking drive" drive"..."
"@echo Checking drive" drive"... >>" File.Temp.Chkdsk
"@chkdsk" drive ">>" File.Temp.Chkdsk
"@echo" copies("─",78) ">>" File.Temp.Chkdsk
i = i + 1
drive = word(map, i)
end
''Pgm.Editor File.Temp.Chkdsk
return
CheckFloppy: procedure expose File.
/**
*** This will check the floppy for data integrity. OS/2 v1.x had problems
*** with my setup. This will excercise I/O to the floppy. It can also
*** serve to stress test a new floppy drive.
**/
arg parms
'@echo Starting floppy stress test:' date() time() '>' File.Temp.3
Pass = 1
do forever
Say "Pass...." Pass
'@copy /v c:\os2\help a: >>' File.Temp.3
Say "Wait...."
call SysSleep 120
Pass = Pass + 1
end
return
CheckSelf: procedure expose Dir. File. Pgm.
/**
*** This is a little self-test routine that will make sure that
*** the relevant directories and files in the global variables exist.
**/
say
say 'Checking directories...'
say
call CheckDir(Dir.BC )
call CheckDir(Dir.BCSource )
call CheckDir(Dir.BCToolkit )
call CheckDir(Dir.Boot )
call CheckDir(Dir.IBMCSource)
call CheckDir(Dir.IBMCPPSource)
call CheckDir(Dir.IBMCPP)
call CheckDir(Dir.IBMWF )
call CheckDir(Dir.Maximus )
call CheckDir(Dir.MSC )
call CheckDir(Dir.MSCSource )
call CheckDir(Dir.ProdCmd )
call CheckDir(Dir.ProdDat )
call CheckDir(Dir.ProdDll )
call CheckDir(Dir.Products )
call CheckDir(Dir.Rexx )
call CheckDir(Dir.Server )
call CheckDir(Dir.SprintMail)
call CheckDir(Dir.Temp )
call CheckDir(Dir.Toolkit13 )
call CheckDir(Dir.Toolkit20 )
call CheckDir(Dir.Unix )
call CheckDir(Dir.VDisk )
say
say 'Checking program files...'
say
call CheckFile(Pgm.Grep)
call CheckFile(Pgm.Editor)
call CheckFile(Pgm.CalcCrc)
call CheckFile(Pgm.Zip)
call CheckFile(Pgm.UnZip)
call CheckFile(Pgm.Awk)
call CheckFile(Pgm.Tail)
call CheckFile(Pgm.Notify)
return
CheckDir: procedure
/**
*** This will check to see if a directory exists
**/
arg DirToCheck
if DirToCheck = 'N/A' then
return 1
DirFound = directory(DirToCheck)
if DirFound \= DirToCheck then
do
say "Directory '"DirToCheck"' was not found"
return 0
end
else
say "Directory '"DirToCheck"' was found"
return 1
CheckFile: procedure
/**
*** This reports on the existence of a file
**/
arg fid
if Exists(fid) then
say "File '"fid"' exists"
else
do
say "File '"fid"' doesn't exist"
return 0
end
return 1
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Other Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
LoadFunctions: procedure
/**
*** This will load the DLL for the Rexx system functions supplied
*** with OS/2 v2.0
***
*** It is recommended that this been run at system startup to assure
*** that the system Rexx functions are available to execs that need
*** them. This approach was chosen for loading the DLL every time the
*** Rexx exec was entered.
**/
call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
call SysLoadFuncs
return
WhereIs: procedure expose Dir. File. Grep. Pgm.
/**
*** This will search for the file passed on the drive set specified
**/
arg FileSpec Drives
select
when abbrev('LOCAL' ,Drives, 1) then
do
map = SysDriveMap('C:', 'LOCAL')
i = 1
drive = word(map, i)
do while(drive \= '')
call WhereisFile drive'\'FileSpec
i = i + 1
drive = word(map, i)
end /* do */
end /* when */
when abbrev('ALL' ,Drives, 1) then
do
map = SysDriveMap('C:', 'USED')
i = 1
drive = word(map, i)
do while(drive \= '')
call WhereisFile drive'\'FileSpec
i = i + 1
drive = word(map, i)
end /* do */
end /* when */
when abbrev('USED' ,Drives, 1) then
do
map = SysDriveMap('C:', 'USED')
i = 1
drive = word(map, i)
do while(drive \= '')
call WhereisFile drive'\'FileSpec
i = i + 1
drive = word(map, i)
end /* do */
end /* when */
otherwise
call WhereisFile FileSpec
end
return
WhereisFile: procedure
/**
*** This will find a single file, starting at the current directory
*** unless a fully qualified filespec is passed.
**/
arg FileSpec
call SysFileTree FileSpec, 'Found', 'FSO'
do i = 1 to Found.0
say Found.i
end
return;
Test: procedure expose Dir. File. Grep. Pgm.
/**
*** This is a spot into which test code can be placed to check some
*** REXX code out easily.
**/
env = value("PROGREF", , "OS2ENVIRONMENT")
say env
return
Modem = Open('COM2:', 'WRITE')
call lineout Modem, "AT&C1V1X4Q0E1S7=60M1"
call SysSleep 2
call lineout Modem, "AT&C1V1X4Q0E1S7=60M1"
call SysSleep 2
Modem = Close(Modem)
return
do i = 10 to 1 by -1
say i
end
say FormatComma(0)
say FormatComma(1)
say FormatComma(123)
say FormatComma(123456)
say FormatComma(1234567)
say FormatComma(12345678)
say FormatComma(123456789)
say FormatComma(1234567890)
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ General Purpose Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
UpperCase: procedure
/**
*** This will return the string passed after converting it to uppercase
**/
parse upper arg String
return String
LowerCase: procedure
/**
*** This will return the string passed after converting it to lowercase
**/
parse lower arg String
return String
PathSplit: procedure expose DirList.
/**
*** This will create a stem variable out of the semicolon-delimited
*** variable that is presumably retreived from a PATH or DPATH
*** environment.
**/
arg PathString .
DirList = ''
j = 1
parse var PathString DirList.j ';' PathString
do while DirList.j \= ''
j = j + 1
parse var PathString DirList.j ';' PathString
end /* while */
DirList.0 = j - 1
return DirList.0
PathRemove: procedure expose DirList.
/**
*** This will remove those items from the directory list that match
*** the prefix of the argument passed.
**/
arg DirPrefix .
i = 1
RemovedCount = 0
do while i <= DirList.0
if abbrev(DirList.i, DirPrefix) then
do
/* Move the rest of the items down */
do j = i to DirList.0
k = j + 1
DirList.j = DirList.k
end /* do j = */
/* Reduce the count and clear out the last entry */
DirList.0 = DirList.0 - 1
DirList.k = ''
RemovedCount = RemovedCount + 1
end /* if */
i = i + 1
end /* while */
return RemovedCount
PathBuild: procedure expose DirList.
/**
*** This will build a semi-colon delimited string with the names of all
*** the directories in the DirList stem variable
**/
PathList = Dirlist.1
do i = 2 to DirList.0
PathList = PathList";"DirList.i
end
return PathList
DeleteOldFiles: procedure
/**
*** This will keep 'x' versions of the filename that matches the
*** pattern passed and delete the rest.
**/
arg SearchFor, Keep
/* Keep the number of message file backups to a reasonable number */
call SysFileTree SearchFor, 'Sort', 'FT'
/* If there are a bunch of them, delete the oldest ones */
if Sort.0 > Keep then
do
call SortStem
do j = 1 to (Sort.0 - Keep)
parse var Sort.j . . . DeleteFile
'erase' DeleteFile
end
end /* if */
return (Sort.0 - Keep)
SortStem: procedure expose Sort.
/**
*** This will sort the stem variable passed in. It is assumed that the
*** stem variable is formatted in the "standard" way of Stem.0 containing
*** the number of items
**/
do i = 1 to Sort.0
/* Find the lowest value in the list */
low = i;
do j = (i+1) to Sort.0
if Sort.j < Sort.low then
low = j
end
/* Swap the two */
temp = Sort.i
Sort.i = Sort.low
Sort.low = temp
end
return
FormatComma: procedure
/**
*** This will take a string (that is presumably numeric, but not verified
*** to be) and insert commas after groups of three digits
**/
arg Raw .
Formatted = ''
do while Raw \= 0
Formatted = right(Raw, 3)','Formatted
Raw = Raw % 1000
end
if Formatted = '' then
Formatted = 0
else
do
Formatted = Strip(Formatted,'Trailing',',')
Formatted = Strip(Formatted,'Leading',' ')
end
return Formatted
Open: procedure
arg file rw
file_ = stream(file,c,'QUERY EXIST')
/* If the file is opened for WRITE access, delete it first */
if (file_ \= '') then
do
if (rw = 'WRITE') then
'@erase' file
file = file_
end
message = stream(file,c,'OPEN' rw)
if (message \= 'READY:') then
do
say 'Error: Open failure on' file'.' message
exit
end
return file
Close: procedure
arg file
message = stream(file,c,'CLOSE')
if (message \= 'READY:') & (message \= '') then
do
say 'Error: Close failure on' file'.' message
exit
end
return file
Exists: procedure
arg file
file = stream(file,c,'QUERY EXIST')
if (file = '') then
return 0
else
return 1