home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
samp$.zip
/
$.CMD
Wrap
OS/2 REXX Batch file
|
1994-12-27
|
88KB
|
2,946 lines
/**
*** ╔════════════════════════════════════════════════════════════════════╗
*** ║ ║
*** ║ $.CMD - version 3.16 ║
*** ║ ║
*** ║ ────────────────────────────────────────────────────────────────── ║
*** ║ ║
*** ║ 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/Fax.. (913) 829-2450 8N1 14.4Kbps ║
*** ║ CIS...... [73457,365] ║
*** ║ ║
*** ║ ────────────────────────────────────────────────────────────────── ║
*** ║ ║
*** ║ Copyright (c) 1992-1994 Hilbert Computing ║
*** ║ ║
*** ╚════════════════════════════════════════════════════════════════════╝
**/
call LoadFunctions
/* The configuration information is kept in an INI file. Make sure this */
/* file exists. */
IniFile = GetIniFile()
/* Parse the command */
parse arg cmd parms
cmd = translate(cmd) /* Convert to uppercase */
/* Save the current directory */
pwd = value("pwd",directory(),"OS2ENVIRONMENT")
select
when abbrev('BACKUP' ,cmd, 3) 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('COPYSAFE' ,cmd, 4) then call CopySafe parms
when abbrev('ENVIRONMENT',cmd, 3) then call Environment parms
when abbrev('FORALL' ,cmd, 6) then call ForAll parms
when abbrev('LIB' ,cmd, 3) then call Lib parms
when abbrev('MAKE' ,cmd, 3) then call Make 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('PSTAT' ,cmd, 2) then call PStat parms
when abbrev('RECURSE' ,cmd, 3) then call Recurse parms
when abbrev('RESET' ,cmd, 3) then call Reset parms
when abbrev('REPEATS' ,cmd, 3) then call Repeats parms
when abbrev('SCANENVIRON',cmd, 4) then call Which parms
when abbrev('SPACE' ,cmd, 2) then call Space parms
when abbrev('SYNCH' ,cmd, 2) then call Synch parms
when abbrev('TRACE' ,cmd, 2) then call Trace parms
when abbrev('WHICH' ,cmd, 1) then call Which parms
when abbrev('ZIP' ,cmd, 1) then call Zip parms
otherwise
say "Command '"cmd"' not recognized"
end /* Select */
/* Return to the starting directory */
pwd = value("pwd",,"OS2ENVIRONMENT")
code = directory(pwd)
exit
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Synch Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Synch: procedure expose IniFile
parse arg cmd parms
parse upper var cmd cmd
select
when abbrev('INI' ,cmd, 3) then call SynchIni parms
when abbrev('DEVL' ,cmd, 4) then call SynchDevelopment parms
when abbrev('C++' ,cmd, 1) then call SynchClass parms
otherwise
say "Subcommand (SYNCH): '"cmd"' not recognized"
end /* Select */
return
SynchClass: procedure expose IniFile
/**
*** This will synch the class library source with the development
*** environment
**/
BaseDir = GetIni('Directory','Products','d:\products')
ClassDir = GetIni('Directory','Class Lib Source','d:\ibmcpp\hsource')
code = directory(ClassDir)
CopyCount = 0
say
say 'Synching message files...'
CopyCount = CopyCount + CopySafe('*.msg' BaseDir'\data')
say
say 'Synching header files...'
CopyCount = CopyCount + CopySafe('*.hpp ..\hclass')
CopyCount = CopyCount + CopySafe('*.h ..\hclass')
call charout ,'Remake object library? '
pull answer
if answer = 'Y' then
do
call Lib 'make hclass'
say
say 'Synching object library...'
CopyCount = CopyCount + CopySafe('hclass.lib ..\hlib')
end
say "Total files synchronized:" CopyCount
return 0
SynchDevelopment: procedure expose IniFile
/**
*** This will synchronize the development tools
**/
parse arg SynchDir
if SynchDir = '' then
do
SynchDir = "A:"
code = directory("A:\")
end
BaseDir = GetIni('Directory','Products','')
'@replace /u' BaseDir'\*' SynchDir
'@replace /u' SynchDir'\*' BaseDir
'@replace /u' BaseDir'\CMD\*' SynchDir'\CMD'
'@replace /u' SynchDir'\CMD\*' BaseDir'\CMD'
return 0
SynchIni: procedure expose IniFile
/**
*** This will synchronize the INI files for WWW, idioms and the Gatekeeper
**/
parse arg SynchDir
if SynchDir = '' then
SynchDir = "A:"
BaseDir = GetIni('Directory','Idioms','d:\idioms')
'@replace /u' BaseDir'\*.ini' SynchDir
'@replace /u' SynchDir'\*.ini' BaseDir
BaseDir = GetIni('Directory','GateKeeper','d:\GateKeeper')
'@replace /u' BaseDir'\*.ini' SynchDir
'@replace /u' SynchDir'\*.ini' BaseDir
BaseDir = value("ETC",,"OS2ENVIRONMENT")
'@replace /u' BaseDir'\*.ini' SynchDir
'@replace /u' SynchDir'\*.ini' BaseDir
'@replace /u' BaseDir'\explore.???' SynchDir
'@replace /u' SynchDir'\explore.???' BaseDir
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Lib Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Lib: procedure expose IniFile
parse arg cmd parms
parse upper var cmd cmd
select
when abbrev('LIST' ,cmd, 5) then call LibList parms
when abbrev('MAKE' ,cmd, 4) then call LibMake parms
otherwise
say "Subcommand (LIB): '"cmd"' not recognized"
end /* Select */
return
LibMake: procedure expose IniFile
/**
*** This will create a library from the object modules in that directory
**/
parse arg library
library = translate(strip(library))
if left(library,4) = '.LIB' then
parse var library library '.LIB' .
if library = '' then
do
call Error 2004,0,"You must specify a library name."
return 16
end
call SysFileTree '*.obj', 'Found', 'FO'
do i = 1 to Found.0
objfile = translate(found.i)
parse var objfile objfile '.OBJ' .
say 'Updating' objfile'...'
'@lib' library '/q -+'objfile';'
end
return 0
LibList: procedure expose IniFile
/**
*** This will augment the inherently crappy LIB utility to search
*** for entry points within a library and to enable usage with
*** utilities like GREP
**/
parse arg library
library = translate(strip(library))
if left(library,4) <> '.LIB' then
library = library'.LIB'
if exists(library) = 0 then
do
call Error 2002,0,library
return
end
tmp = value("TMP",,"OS2ENVIRONMENT")
if tmp = '' then
do
call Error 2008,0,'TMP','Defaulting to current directory'
tmp = '.'
end
/* Clean up any files from past runs */
'@del' tmp'\$LIB????.LIB 2>NUL'
'@del' tmp'\$LIB????.LST 2>NUL'
templib = SysTempFileName(tmp'\$LIB????.LIB')
templst = SysTempFileName(tmp'\$LIB????.LST')
say 'Generating listing for' library'. Please wait...'
'@copy' library templib '1>NUL'
'@lib /nologo' templib','templst
'@type' templst
code = SysFileDelete(templib)
code = SysFileDelete(templst)
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Make Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Make: procedure expose IniFile
/**
*** This will call the NMAKE code with some preprocessing for managing
*** projects
**/
parse arg Options
Opt. = ''
Opt.Flag.Q = '-' /* Default to display "Done" msg */
Opt.Flag.E = '+' /* Edit the output */
Opt.Flag.D = '+' /* Debug */
Opt.Flag.O = '-' /* Old Make */
Opt.Flag.L = '-' /* Create DLL */
EnvOpt = value("MMAKE.OPT",,"OS2ENVIRONMENT")
call ParseOptions EnvOpt Options
if Opt.Flag.SYNTAX = '+' then
do
call MakeSyntax
return
end
Project = Opt.Parm.1
Opt.Flag.S = translate(Opt.Flag.S)
/* If nothing was passed, use an environment variable */
if project = '' then
project = value("PROJECT",,"OS2ENVIRONMENT")
if project = '' then
do
say "I don't know what to MAKE"
exit
end
makefile = project'.mak'
temp = project'.tmp'
/* Get rid of the old temp file */
if Exists(temp) then '@erase' temp
/* Parse and process the options */
if Opt.Parm.O = '+' then
make = "@make"
else
make = "@nmake /NOLOGO"
macros = ""
if Opt.Flag.D = '+' then macros = '"DEBUG=Y"' macros
if Opt.Flag.L = '+' then macros = '"DLL=Y"' macros
select
when pos("D",Opt.Flag.S) > 0 then macros = '"DBM=Y"' macros
when pos("T",Opt.Flag.S) > 0 then macros = '"TCP=Y"' macros
when pos("C",Opt.Flag.S) > 0 then macros = '"CM=Y"' macros
when pos("R",Opt.Flag.S) > 0 then macros = '"REXX=Y"' macros
otherwise
nop
end /* select */
/* Invoke the proper MAKE utility with the proper options */
call Time('Reset')
make macros makefile
say "The make took" Format(Time("Elapsed"),,2) "seconds."
/* Display the completion dialog box and edit the output */
if Opt.Flag.Q = '-' then
do
parse upper var project project
Notify = GetIni('Program','Notify','msg.exe')
'@'Notify 'Make for' project 'complete.'
end
if Opt.Flag.E = '+' then
if Exists(temp) then
do
'pause'
'@kedit' temp
end
return
MakeSyntax: procedure
/**
*** This will display the syntax for the MAKE subcommand
**/
say "SYNTAX: $ MAKE [[[[[-q] -e] -s{d|t|c|r}] -l] [project]"
say " where: q - quiet"
say " e - edit"
say " s - subsystem flags as follows:"
say " d - DB2/2"
say " t - TCP/IP"
say " c - CM/2"
say " r - REXX"
say " l - create DLL"
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Backup Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Backup: procedure expose IniFile
parse arg cmd parms
parse upper var cmd cmd
select
when abbrev('CHRON' ,cmd, 5) then call BackupChron parms
when abbrev('CONFIG' ,cmd, 4) then call BackupConfig parms
otherwise
say "Subcommand (BACKUP): '"cmd"' not recognized"
end /* Select */
return
BackupConfig: procedure expose IniFile
/**
*** 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)
**/
Boot = GetIni('Directory','Boot','c:\')
Backup = GetIni('Directory','Backup','d:\backup')
call SysFileTree Boot'CONFIG.SYS', 'Found', 'F', '+****', '-****'
if Found.0 then
do
FileExt = right(date("days"),3,"0") /* Julian date padded w/ 0's */
'copy' Boot'CONFIG.SYS' Backup'\CONFIG.'FileExt
'@attrib -A' Boot'CONFIG.SYS'
end
/* Keep the number of config backups to a reasonable number */
DeleteCount = DeleteOldFiles(Backup'\CONFIG.*', 10)
return;
BackupChron: procedure expose IniFile
/**
*** 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 */
ChronDir = GetIni('Directory','Chron','')
BackupDir = GetIni('Directory','Backup','')
'copy' ChronDir'\chron.dat' BackupDir'\'Destination
return;
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ CopySafe Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
CopySafe: procedure expose IniFile
/**
*** This will check the time/date stamps on the files before copying
*** them.
**/
parse arg Options
/* Set defaults and parse the command line parameters */
Opt.Flag.P = '-' /* Don't prompt before copying */
Opt.Flag.C = '-' /* Don't compare before copying */
Opt.Flag.V = '-' /* Default to non-verbose output */
Opt.Parm.2 = '.' /* Dest defaults to current directory */
call ParseOptions Options
if Opt.Flag.SYNTAX = '+' then
call Syntax
if Opt.Flag.C = '+' then
Opt.Flag.P = '+'
/* The destination must be a directory */
DestDir = QualifiedDirectory(Opt.Parm.2)
if DestDir = '' then
do
call Error 2003,0,Opt.Parm.2
return 0
end
if Opt.Flag.C = '+' then
contrast = GetIni('Program','Contrast','contrast.exe')
/* Generate the list of file to potentially copy */
CopyCount = 0
call SysFileTree Opt.Parm.1,'File','f'
do i = 1 to File.0
code = CopyFile(File.i, DestDir)
end
say " " CopyCount "file(s) copied."
return CopyCount
CopyFile: procedure expose Opt. CopyCount contrast
/**
*** Copy the file to the destination if the dest is older than the
*** source. Otherwise, compare or prompt as appropriate.
**/
parse arg fdate ftime . . SourceFile, DestDir
DestDir = strip(DestDir,'Trailing','\')
DestFile = DestDir'\'filespec('Name',SourceFile)
SourceFile = strip(SourceFile,'Both')
/* See if the file exists */
call SysFileTree DestFile,'File','F'
select
when File.0 = 0 then /* No file */
CopyState = 'Yes'
when File.0 = 1 then /* Found */
do
parse var File.1 dfdate dftime .
TimeStamp = CompareFileTimes(dfdate dftime,fdate ftime)
select
when TimeStamp = '<' then
CopyState = 'Conditional'
when TimeStamp = '=' then
CopyState = 'No'
otherwise
CopyState = 'Conditional'
end /* select */
end
otherwise
return 4
end /* select */
if CopyState = 'Conditional' then
do
/* Do any necessary displays and prompting */
if Opt.Flag.C = '+' then
'@'contrast SourceFile DestFile
if Opt.Flag.P = '+' then
do
say 'Copy: ('left(fdate ftime, 16)')' SourceFile
call charout ,'To: ('left(dfdate dftime, 16)')' DestFile'? '
CopyState = GetPromptForCopy()
end /* Prompt */
else
CopyState = 'Yes'
end /* conditional */
if CopyState = 'Yes' then
do
if Opt.Flag.V = '+' then
say 'Copying "'SourceFile'" to "'DestFile'"...'
else
say SourceFile
'@COPY' SourceFile DestFile '> nul'
CopyCount = CopyCount + 1
end
else
if Opt.Flag.V = '+' then
say 'Skipping "'SourceFile'"...'
return 0
GetPromptForCopy: procedure
/**
*** This will get the response from the prompt for copy
**/
Key = SysGetKey('NOECHO')
Key = translate(Key)
if Key = 'Y' then
do
/* Verify */
call charout ,"Sure?"
Key = SysGetKey('NOECHO')
Key = translate(Key)
if Key = 'Y' then
CopyState = 'Yes'
else
CopyState = 'No'
end
else
CopyState = 'No'
say
return CopyState
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ ForAll Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
ForAll: procedure expose IniFile
/**
*** This will execute the command for each file in the list
**/
parse arg FileList Cmd
/* Set defaults and parse the command line parameters */
call ParseOptions Options
call SysFileTree FileList, 'Found', 'FO'
do i = 1 to Found.0
if pos('%',Cmd) = 0 then
ExecCmd = Cmd Found.i
else
ExecCmd = MapSymbol(Cmd, '%', Found.i)
'@'ExecCmd
end
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Repeats Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Repeats: procedure expose IniFile
/**
*** This will list the files that are duplicated on a series of disks
**/
arg DriveList
if DriveList = '' then
DriveList = SysDriveMap('C:', 'LOCAL')
List. = ''
List.0 = 0
Compare. = ''
Compare.0 = 0
Dups. = ''
Dups.0 = 0
do i = 1 to words(DriveList)
Drive = left(word(DriveList, i),1)
say "Obtaining files list for drive" Drive"..."
call SysFileTree Drive':\*','More','SF'
say "Found" More.0 "files."
/* Move this files to the end of the list */
do j = 1 to More.0
parse var More.j . . . . FullName
Name = FileSpec("name",FullName)
w = List.0 + j
List.w = More.j
Compare.w = translate(Name)
end
List.0 = List.0 + More.0
end
/* Search for duplicates */
say "Searching for duplicates. Total files:" List.0". This may take a long time."
say "A '.' means the list has been scanned for a file. A '+' means a match."
do i = 1 to List.0
call charout ,"."
do j = (i+1) to List.0
if List.j <> '' then
do
if Compare.i == Compare.j then
do
w = Dups.0 + 1
Dups.0 = w
Dups.w = Compare.i"~"List.i"~"List.j
call charout ,"+"
List.j = ''
end
end
end
end
say
Repeats = GetIni('File','Repeats','d:\temp\repeats.out')
Repeats = Open(Repeats,'WRITE')
do i = 1 to Dups.0
parse var Dups.i UpCase "~" Date1 Time1 Size1 . Full1 "~" Date2 Time2 Size2 . Full2
Name = filespec("name",Full1)
call lineout Repeats,Name
call lineout Repeats,right(Date1,12) right(Time1,9) right(Size1,11) Full1
call lineout Repeats,right(Date2,12) right(Time2,9) right(Size2,11) Full2
end
code = Close(Repeats)
Editor = GetIni('Program','Editor','e.exe')
'@'editor Repeats
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Reset Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Reset: procedure expose IniFile
/**
*** The PROFILE command will configure an OS/2 command prompt session
**/
parse arg cmd parms
cmd = translate(cmd)
select
when abbrev('ENVIRONMENT',cmd, 3) then call ResetEnvironment parms
when abbrev('SET' ,cmd, 3) then call ResetEnvironment parms
when abbrev('PROFILE' ,cmd, 3) then call ResetProfile parms
otherwise
say "Subcommand (RESET): '"cmd"' not recognized"
end /* Select */
return
ResetProfile: procedure expose IniFile
/**
*** This will remove the current parameters for the project information
*** used by the PROFILE command. The next time the PROFILE subcommand
*** is run, it will prompt for the new values.
**/
Opt. = ''
Opt.Flag.P = '+' /* Default to prompting for which to delete */
parse arg Options
call ParseOptions Options
project = Opt.Parm.1
if project = '' then
project = value("PROJECT",,"OS2ENVIRONMENT")
if project = '' then
do
call Error 2004,0
return
end
project = LowerCase(project)
Application = 'Project:' project
if Opt.Flag.P = '-' then
code = SysIni(Inifile, Application, 'DELETE:')
else
do
code = SysIni(Inifile,Application, 'ALL:','key')
do i = 1 to key.0
IniValue = SysIni(IniFile,Application, key.i)
if IniValue = 'ERROR:' then IniValue = ''
say "Enter value for"
say " Key: '"key.i"'"
say " Default: '"IniValue"'"
call charout ,"> "
parse pull IniValue
if IniValue <> '' then
code = SysIni(IniFile,Application,key.i,IniValue)
end /* do i... */
end
say 'Entry reset for Project:' project'.'
call charout ,"Re-profile? "
pull answer
if answer = "Y" then
call Profile project
return
ResetEnvironment: procedure expose IniFile
/**
*** This will reset the enviroment variables back to the values in the
*** CONFIG.SYS
**/
Grep = GetIni('Program','Grep','grep.exe')
Boot = GetIni('Directory','Boot','c:\')
'@'Grep '-i "^set .*\="' Boot'config.sys | rxqueue'
say 'Resetting' queued() 'environment variables...'
do i = 1 to queued()
parse pull SetStatement
'@'SetStatement
end
say 'Done.'
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Profile Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Profile: procedure expose IniFile
/**
*** The PROFILE command will configure an OS/2 command prompt session
**/
parse arg cmd project .
/**
*** Determine if this is using the profile type from the command line
*** (two positional words) or if it is using the information in the
*** profile to determine what the type is.
**/
if project = '' then /* use the profile */
do
project = cmd /* Shift the parameters down 1 */
cmd = GetProfile(project,'Project Type','IBMCPP')
end
cmd = translate(cmd)
/* Change the number of lines on the screen */
mode = GetIni('Global','Mode','co80,25')
'@mode' mode
call SysCls
say 'Setting environment variables...'
project = LowerCase(project)
if project = '' then
do
call Error 2004,0
return
end
select
when abbrev('AWK' ,cmd, 1) then call ProfileAWK project
when abbrev('IBMC' ,cmd, 3) then call ProfileIBM project
when abbrev('IBMCPP' ,cmd, 5) then call ProfileIBM project
when abbrev('CPP' ,cmd, 5) then call ProfileIBM project
when abbrev('CSET' ,cmd, 5) then call ProfileIBM project
when abbrev('IPF' ,cmd, 3) then call ProfileIPF project
when abbrev('INF' ,cmd, 3) then call ProfileIPF project
when abbrev('BUILDINF',cmd, 5) then call ProfileIPF project
when abbrev('BUILDIPF',cmd, 7) then call ProfileIPF project
when abbrev('MSFTC' ,cmd, 2) then call ProfileMS project
when abbrev('MSC' ,cmd, 2) then call ProfileMS project
when abbrev('REXX' ,cmd, 2) then call ProfileRexx project
when abbrev('CMD' ,cmd, 2) then call ProfileRexx project
when abbrev('GENERIC' ,cmd, 1) then call ProfileGeneric project
when abbrev('.' ,cmd, 1) then call ProfileGeneric project
when abbrev('X' ,cmd, 1) then call ProfileGeneric project
otherwise
say "Subcommand (PROFILE): '"cmd"' not recognized"
end /* Select */
return
ProfileIBM: procedure expose IniFile
/**
*** This will configure an OS/2 session for using the IBM C Set
*** compiler
**/
parse arg project
NoAdditional = 'No Additional Paths'
/* Get profile information */
Toolkit = GetIni('Directory','2.x Toolkit','')
CBase = GetIni('Directory','IBM C Base','')
ext = GetProfile(project,'Default Ext','cpp')
spath = GetProfile(project,'Source Path',directory())
apath = GetProfile(project,'Archive Path',spath'\Archive')
addlinc = GetProfile(project,'Additional include paths',NoAdditional)
addllib = GetProfile(project,'Additional LIB paths',NoAdditional)
mpath = GetProfile(project,'Make Path','d:\products\data')
defmake = GetProfile(project,'Default make options','-e -d')
/* Create the archive directory if one doesn't exist */
if Exists(spath) = 0 then
code = SysMkDir(spath)
if Exists(apath) = 0 then
code = SysMkDir(apath)
say "Refreshing the NMAKE386.INC file from" mpath"..."
'@copy' mpath'\nmake386.inc' spath
if addlinc = NoAdditional then
addlinc = ''
else
addlinc = strip(addlinc,'Trailing',';')';'
if addllib = NoAdditional then
addllib = ''
else
addllib = strip(addllib,'Trailing',';')';'
Include = addlinc||Toolkit"\cplus\os2h;"Toolkit"\c\os2h;"CBase"\include;"CBase"\ibmclass;"CBase"\HClass"
Lib = addllib||Toolkit"\os2lib;"CBase"\lib;"CBase"\HLib"
Env = value("PROJECT" ,project ,"OS2ENVIRONMENT")
Env = value("Last Kedit File",project"."ext ,"OS2ENVIRONMENT")
Env = value("INCLUDE" ,Include ,"OS2ENVIRONMENT")
Env = value("INCLUDETOOLS" ,Toolkit"\c\os2h" ,"OS2ENVIRONMENT")
Env = value("INCLUDEC" ,CBase"\include;"CBase"\ibmclass","OS2ENVIRONMENT")
Env = value("LIB" ,Lib ,"OS2ENVIRONMENT")
Env = value("IPFC" ,Toolkit"\ipfc" ,"OS2ENVIRONMENT")
Env = value("MMAKE.OPT" ,defmake ,"OS2ENVIRONMENT")
Env = value("SOURCEPATH" ,spath ,"OS2ENVIRONMENT")
Env = value("ARCHIVEPATH" ,apath ,"OS2ENVIRONMENT")
Env = value("MAKEPATH" ,mpath ,"OS2ENVIRONMENT")
/* Re-build the path with the executables for this compiler and toolkit */
/* in front. */
EnvVal = value("PATH", , "OS2ENVIRONMENT")
EnvPath = value("PATH", CBase"\bin;"Toolkit"\os2bin;"EnvVal, "OS2ENVIRONMENT")
/* Do the same to the HELP environment variable */
EnvVal = value("HELP", , "OS2ENVIRONMENT")
EnvHelp = value("HELP", Toolkit"\os2help;"EnvVal, "OS2ENVIRONMENT")
/* Do the same to the BOOKSHELF environment variable */
EnvVal = value("BOOKSHELF", , "OS2ENVIRONMENT")
EnvBook = value("BOOKSHELF", CBase"\book;"Toolkit"\book;"EnvVal, "OS2ENVIRONMENT")
pwd = value("pwd",spath,"OS2ENVIRONMENT") /* Change default directory */
return
ProfileMS: procedure expose IniFile
/**
*** This will configure an OS/2 session for using MSC and the OS/2 v1.3
*** Toolkit
**/
parse arg project
/* Get profile information */
Toolkit = GetIni('Directory','1.3 Toolkit','')
CBase = GetIni('Directory','IBM C Base','')
ext = GetProfile(project,'Default Ext','c')
spath = GetProfile(project,'Source Path',directory())
apath = GetProfile(project,'Archive Path',spath'\Archive')
mpath = GetProfile(project,'Make Path','d:\products\data')
defmake = GetProfile(project,'Default make options','-e -d')
Env = value("PROJECT", project, "OS2ENVIRONMENT")
Env = value("Last Kedit File", project"."ext ,"OS2ENVIRONMENT")
Env = value("INCLUDE", Toolkit"\c\include;"CBase"\include","OS2ENVIRONMENT")
Env = value("INCLUDETOOLS", Toolkit"\c\include", "OS2ENVIRONMENT")
Env = value("INCLUDEC", CBase"\include", "OS2ENVIRONMENT")
Env = value("LIB", Toolkit"\lib;"CBase"\lib" , "OS2ENVIRONMENT")
Env = value("IPFC", Toolkit"\ipfc" , "OS2ENVIRONMENT")
Env = value("MMAKE.OPT" ,defmake ,"OS2ENVIRONMENT")
Env = value("SOURCEPATH" ,spath ,"OS2ENVIRONMENT")
Env = value("ARCHIVEPATH" ,apath ,"OS2ENVIRONMENT")
Env = value("MAKEPATH" ,mpath ,"OS2ENVIRONMENT")
EnvPath = value("PATH", , "OS2ENVIRONMENT")
EnvPath = value("PATH", CBase"\bin;"Toolkit"\bin;"EnvPath, "OS2ENVIRONMENT")
/* Do the same to the HELP environment variable */
EnvHelp = value("HELP", , "OS2ENVIRONMENT")
EnvHelp = value("HELP", Toolkit"\os2help;"EnvHelp, "OS2ENVIRONMENT")
pwd = value("pwd",spath,"OS2ENVIRONMENT") /* Change default directory */
return
ProfileRexx: procedure expose IniFile
/**
*** This will configure an OS/2 session for working with REXX
**/
parse arg project
RexxDir = GetIni('Directory','REXX','')
ext = GetProfile(project,'Default Ext','rex')
spath = GetProfile(project,'Source Path',directory())
apath = GetProfile(project,'Archive Path',spath'\Archive')
mpath = GetProfile(project,'Make Path','d:\products\data')
defmake = GetProfile(project,'Default make options','-e- -q')
say "Refreshing the NMAKE386.INC file from" mpath"..."
'@copy' mpath'\nmake386.inc' spath
Env = value("INCLUDE" ,RexxDir"\Include" ,"OS2ENVIRONMENT")
Env = value("PROJECT" ,project ,"OS2ENVIRONMENT")
Env = value("Last Kedit File" ,project"."ext ,"OS2ENVIRONMENT")
Env = value("MMAKE.OPT" ,defmake ,"OS2ENVIRONMENT")
Env = value("SOURCEPATH" ,spath ,"OS2ENVIRONMENT")
Env = value("ARCHIVEPATH" ,apath ,"OS2ENVIRONMENT")
Env = value("MAKEPATH" ,mpath ,"OS2ENVIRONMENT")
pwd = value("pwd",spath,"OS2ENVIRONMENT") /* Change default directory */
return
ProfileAWK: procedure expose IniFile
/**
*** This will configure an OS/2 session for AWK development
**/
parse arg project
Env = value("PROJECT", project, "OS2ENVIRONMENT")
Env = value("Last Kedit File", project".awk" , "OS2ENVIRONMENT")
return
ProfileIPF: procedure expose IniFile
/**
*** This will configure an OS/2 session for IPF (View Books) development
**/
parse arg project
Include = GetIni('Directory','IPF Include','')
ext = GetProfile(project,'Default Ext','ipf')
spath = GetProfile(project,'Source Path',directory())
apath = GetProfile(project,'Archive Path',spath'\Archive')
mpath = GetProfile(project,'Make Path','d:\products\data')
defmake = GetProfile(project,'Default make options','-e- -q')
say "Refreshing the NMAKE386.INC file from" mpath"..."
'@copy' mpath'\nmake386.inc' spath
Env = value("INCLUDE" ,Include ,"OS2ENVIRONMENT")
Env = value("PROJECT" ,project ,"OS2ENVIRONMENT")
Env = value("Last Kedit File" ,project"."ext ,"OS2ENVIRONMENT")
Env = value("MMAKE.OPT" ,defmake ,"OS2ENVIRONMENT")
Env = value("SOURCEPATH" ,spath ,"OS2ENVIRONMENT")
Env = value("ARCHIVEPATH",apath ,"OS2ENVIRONMENT")
Env = value("MAKEPATH" ,mpath ,"OS2ENVIRONMENT")
pwd = value("pwd",spath,"OS2ENVIRONMENT") /* Change default directory */
return
ProfileGeneric: procedure expose IniFile
/**
*** This will configure an OS/2 session for a generic work environment
*** It will set the mode, PROJECT and and profile variables.
**/
parse arg project
ext = GetProfile(project,'Default Ext','ipf')
spath = GetProfile(project,'Source Path',directory())
apath = GetProfile(project,'Archive Path',spath'\Archive')
mpath = GetProfile(project,'Make Path','d:\products\data')
defmake = GetProfile(project,'Default make options','-e- -q')
say "Refreshing the NMAKE386.INC file from" mpath"..."
'@copy' mpath'\nmake386.inc' spath
Env = value("PROJECT" ,project ,"OS2ENVIRONMENT")
Env = value("Last Kedit File" ,project"."ext ,"OS2ENVIRONMENT")
Env = value("MMAKE.OPT" ,defmake ,"OS2ENVIRONMENT")
Env = value("SOURCEPATH" ,spath ,"OS2ENVIRONMENT")
Env = value("ARCHIVEPATH",apath ,"OS2ENVIRONMENT")
Env = value("MAKEPATH" ,mpath ,"OS2ENVIRONMENT")
pwd = value("pwd",spath,"OS2ENVIRONMENT") /* Change default directory */
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Trace Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Trace: procedure expose IniFile
/**
*** This will trace the feature that is specified
**/
parse arg cmd parms
cmd = translate(cmd)
/* Change the number of lines on the screen */
select
when abbrev('APPC' ,cmd, 1) then call TraceAPPC parms
otherwise
say "Subcommand (TRACE): '"cmd"' not recognized"
end /* Select */
return
TraceAPPC: procedure expose IniFile
/**
*** This will trace CM/2 APPC traffic
**/
'@cmtrace start /api appc /data ibmtrnet /reset > NUL'
say 'Trace started. Perform the APPC-based transaction that you want to trace.'
say 'When the APPC transaction to be traced is complete, press any key.'
call Pause
'@cmtrace stop > NUL'
say "APPC trace stopped."
/* Get the name of the trace file */
Editor = GetIni('Program','Editor','e.exe')
Trace = GetIni('File','Trace','d:\temp\trace.out')
say "Erasing old trace file..."
'@erase' Trace "> NUL 2>NUL"
say "Copying from internal trace buffers..."
'@cmtrace copy' Trace "> NUL"
say "Formatting trace data..."
'@fmttrace /DASHF' Trace "> NUL"
/* Construct the name of the detail file and edit it */
Detail = FileSpec("drive", Trace) || FileSpec("Path",Trace) || RootName(Trace)".Det"
'@'editor Detail
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Zip Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Zip: procedure expose IniFile
/**
*** 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
end
TempDir = GetIni('Directory','Temp','')
Zip = GetIni('Program','Zip','')
/* Make a copy of the existing ZIP file if there is one */
ZipDest = 'archive\'ZipFile'.ZIP'
if Exists(ZipDest) then
do
'@copy' ZipDest TempDir
'@del' ZipDest
end
'@'Zip '-o@' ZipDest '< archive\'ZipFile'.zpl'
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Recurse Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Recurse: procedure expose IniFile
/**
*** This will execute the command on each directory starting with
*** the first
**/
parse arg command
call RecurseDirectory ".", command
return
RecurseDirectory: procedure expose IniFile
/**
*** This will execute the command against this direct and all children
**/
parse arg dir, command
old = directory(dir)
say left("---" directory() copies('-',79), 79)
'@'command
call SysFileTree '.', 'Current', 'DO'
do i = 1 to Current.0
call RecurseDirectory Current.i, command
end
return 0
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Space Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Space: procedure expose IniFile
/**
*** 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
/* Get the INI values */
TempFile = GetIni('File','Temp Space','c:\temp.1')
Editor = GetIni('Program','Editor','e.exe')
/* Erase the old and open a new file */
'@erase' TempFile '> nul'
ReportFile = Open(TempFile '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 */
'@'Editor TempFile
return
SpaceDirectory: procedure expose Report.
/**
*** 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
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Pstat Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
PStat: procedure expose IniFile
/**
*** This will place you in the editor on a list of files that was
*** generated from the PSTAT command
**/
arg parms
if parms = 'ALL' then
pstatopt = ''
else
pstatopt = '/c'
say "Working. Please wait..."
Editor = GetIni('Program','Editor','e.exe')
TempFile = GetIni('File','Temp 2','c:\temp.1')
'@pstat' pstatopt '>' TempFile
'@'Editor TempFile
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Migrate Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Migrate: procedure expose IniFile
/**
*** 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 IniFile
/**
*** 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())
call MigrateByExt Project'.EXE'
return
MigrateByExt: procedure expose IniFile
/**
*** 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
ProdDLL = GetIni('Directory','Products DLL','')
ProdCmd = GetIni('Directory','Products Command','')
Products = GetIni('Directory','Products','')
parse var FileSpec FileName '.' FileExt
select
when FileExt = 'DLL' then Target = ProdDll
when FileExt = 'CMD' then Target = ProdCmd
when FileExt = 'EXE' then Target = Products
otherwise
do
say "Unrecognized extension:" FileExt". No action taken."
return
end
end /* select */
'copy' FileSpec Target
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Maximus Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Maximus: procedure expose IniFile
parse arg cmd parms
cmd = translate(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 IniFile
/**
*** 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'
/* Get the INI information */
MaxDir = GetIni('Directory','Maximus','')
Grep = GetIni('Program','Grep','GREP.EXE')
MaxLog = GetIni('File','Maximus Log','')
TempFile = GetIni('File','Temp 1','')
MaxDir = directory(MaxDir)
Grep '"^[\+\=]"' MaxLog '>' TempFile
'@copy' TempFile MaxLog
/* Clean up the temporary files */
'@erase' TempFile
return
MaximusCleanFiles: procedure expose IniFile
/**
*** 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.
**/
/* Get the INI information */
MaxDir = GetIni('Directory','Maximus','')
BBSFile = GetIni('File','Maximus BBS File','')
'@erase' TempFile
map = SysDriveMap('C:', 'USED')
i = 1
drive = word(map, i)
do while(drive \= '')
call SysFileTree drive'\'BBSFile, '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 IniFile
/**
***
**/
'@echo off'
MaxDir = GetIni('Directory','Maximus','')
Grep = GetIni('Program','Grep','GREP.EXE')
MaxLog = GetIni('File','Maximus Log','')
MaxDir = directory(MaxDir)
Grep '"^\+.*calling ("' MaxLog
return
MaximusDownloads: procedure expose IniFile
/**
***
**/
MaxDir = GetIni('Directory','Maximus','')
Grep = GetIni('Program','Grep','GREP.EXE')
MaxLog = GetIni('File','Maximus Log','')
Awk = GetIni('Program','Awk','gawk.exe')
AwkDir = GetIni('Directory','Awk','')
TempFile = GetIni('File','Temp Maximus Download','c:\temp.1')
Editor = GetIni('Program','Editor','e.exe')
'@echo off'
MaxDir = directory(MaxDir)
Awk '-f' AwkDir'\MaxDLByFile.awk' MaxLog '>' TempFile
Awk '-f' AwkDir'\MaxDL.awk' MaxLog '>>' TempFile
Editor TempFile
return
MaximusToday: procedure expose IniFile
/**
***
**/
MaxDir = GetIni('Directory','Maximus','')
MaxLog = GetIni('File','Maximus Log','')
Awk = GetIni('Program','Awk','gawk.exe')
AwkDir = GetIni('Directory','Awk','')
MaxDir = directory(MaxDir)
parse value date('N') with dd mmm .
dd = right(dd, 2, '0')
"@"Grep '"'dd mmm'"' MaxLog '|' Awk '-f' AwkDir'\MaxToday.AWK'
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Environment Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Environment: procedure expose IniFile
/**
*** This will display 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 .
if EnvVariable = '' then
EnvVariable = 'PATH'
/* Take care of the special case for LIBPATH */
if EnvVariable = 'LIBPATH' then
EnvValue = GetLibpath()
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
Which: procedure expose IniFile
parse arg Options
Opt. = ''
Opt.Flag.E = 'PATH'
call ParseOptions Options
File = Opt.Parm.1
fspec = ScanEnvironment(Opt.Flag.E,File)
if fspec = '' then
call Error 2002,0,File
else
say fspec
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Check Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Check: procedure expose IniFile
parse arg cmd parms
cmd = translate(cmd)
select
when abbrev('DRIVES' ,cmd, 2) then call CheckDrives parms
when abbrev('GOPHER' ,cmd, 1) then call CheckGopher parms
when abbrev('MAIL' ,cmd, 2) then call CheckMail parms
when abbrev('MOUNTS' ,cmd, 2) then call CheckMount parms
when abbrev('OS2BBS' ,cmd, 3) then call CheckOS2BBS parms
when abbrev('BBS' ,cmd, 3) then call CheckOS2BBS parms
when abbrev('NETSTAT' ,cmd, 3) then call CheckNetStat parms
otherwise
say "Subcommand (CHECK): '"cmd"' not recognized"
end /* Select */
return
CheckGopher: procedure expose IniFile
/**
*** This will validate that all of the files listed in the Gopher
*** menus really exist.
**/
arg menufile .
if right(menufile,4) \= '.MNU' then
menufile = menufile'.MNU'
if menufile = '' then
do
call Error 2004,0,"MenuFile"
return 16
end
/* Get the source path and change to it */
spath = GetProfile('gopher','Source Path',directory())
code = directory(spath)
/* Open the Gopher filter and read the assiciative array information */
Dir. = ''
Dir.GOPHER = spath
filter = open('GoFilter.70','Read')
do while(lines(filter) > 0)
line = linein(filter)
parse var line "Dir." extension "=" . "'" path "'" comment
if comment \= '' then
interpret line
end /* while */
code = close(filter)
/* Open the menu file */
menu = open(menufile,'read')
call linein menu
call linein menu
do while(lines(menu) > 0)
line = linein(menu)
parse var line . ';' selector .
if left(selector,1) = '[' then
do
parse var selector '[' code ']' request
request = strip(request, 'Both')
code = translate(code)
parse var code subdir '!' format
if format = 'TEXT' then format = ''
if subdir = '' then subdir = 'GOPHER'
end
else
do
format = ''
subdir = 'GOPHER'
request = selector
end
if Dir.subdir = '' then
subdir = 'GOPHER'
select
when selector = '' then /* Initial request */
nop
when code = 'STRING' then /* String */
nop
when code = 'CONTROL' then /* control */
nop
otherwise /* Menus, et. al */
if Exists(Dir.subdir'\'request) = 0 then
do
call Error 2002,0,Dir.subdir'\'request
errorcode = 16
end
end /* select */
end /* while */
code = close(menu)
return errorcode
CheckNetStat: procedure expose IniFile
/**
*** This will check the TCP/IP routing information and make sure that
*** the default route is set up correctly.
**/
/* Clear the queue */
do i = 1 to queued()
pull .
end
'@netstat -r | rxqueue'
pull . /* Header line */
pull . /* Header line */
pull . /* Header line */
OK = 1
defaultFound = 0 /* Make sure there is a default route */
do i = 1 to queued()
parse pull destination router .
select
when destination = 'default' then
do
defaultFound = 1
if router <> '144.223.12.33' then
OK = 0
end
when destination = '144.223.12.0' then
do
if router <> '144.223.12.3' then
OK = 0
end
when destination = '144.223.12.60' then
do
if router <> '144.223.12.61' then
OK = 0
end
when destination = '144.223.12.61' then
do
if router <> '144.223.12.60' then
OK = 0
end
otherwise
OK = 0
end /* select */
end /* do */
if defaultFound = 0 then
OK = 0
if OK = 0 then
do
'@route -fh'
'@arp -f'
'@route add default 144.223.12.33 1'
Notify = GetIni('Program','Notify','msg.exe')
'@'Notify 'Default route definition was reset.'
end
return
CheckMount: procedure expose IniFile
/**
*** This will check to see if the NFS drives are mounted. If not,
*** a mount is attempted.
**/
MountList = 'L: N: R:'
DriveList = SysDriveMap('C:', 'REMOTE')
if wordpos('L:', DriveList) = 0 then
'@net use L: \\KSOPKR01\PUBLIC'
if wordpos('N:', DriveList) = 0 then
call ! 'mount n: ts54sys5:/home/cid'
if wordpos('R:', DriveList) = 0 then
call ! 'mount r: ts54sys1:/home/share'
DriveList = SysDriveMap('C:', 'REMOTE')
do i = 1 to words(MountList)
Drive = word(MountList,i)
if wordpos(Drive, DriveList) = 0 then
do
Notify = GetIni('Program','Notify','msg.exe')
'@'Notify 'One or more of the remote drives did not mount properly.'
return
end
end
return
CheckMail: procedure expose IniFile
/**
*** 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.
**/
MailDir = GetIni('Directory','SprintMail','')
call SysFileTree MailDir'\IN.BOX\*.ASC', 'Found', 'F', '+****', '-****'
if Found.0 > 0 then
do
Notify = GetIni('Program','Notify','msg.exe')
'@'Notify 'You have new SprintMail'
end
return
CheckOS2BBS: procedure expose IniFile
/**
*** This will see if there has been any new OS2BBS information loaded
*** down from IBMLink
***
*** This is intended to be run by CHRON.
**/
BBSDir = GetIni('Directory','OS/2 BBS','')
call SysFileTree BBSDir'\Data\*', 'Found', 'F', '+****', '-****'
if Found.0 > 0 then
do
Notify = GetIni('Program','Notify','msg.exe')
'@'Notify 'You have new information from OS2BBS on IBMLink'
end
return
CheckDrives: procedure expose IniFile
/**
*** This will run a CHKDSK on both the local drives and pipe the output
*** into a file. Once both have been run, the editor is started with the
*** output file to display the results. This is intended to be run by
*** CHRON.
**/
TempFile = GetIni('File','Temp Check Disk','c:\temp.1')
'@erase' TempFile
map = SysDriveMap('C:', 'LOCAL')
i = 1
drive = word(map, i)
do while(drive \= '')
say "Checking drive" drive"..."
"@echo Checking drive" drive"... >>" TempFile
"@chkdsk" drive ">>" TempFile
"@echo" copies("─",78) ">>" TempFile
i = i + 1
drive = word(map, i)
end
Editor = GetIni('Program','Editor','e.exe')
'@'Editor TempFile
return
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Support Routines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
GetProfile: procedure expose IniFile
/**
*** This will get project-specific profile data from the INI file
**/
parse arg Project,Key,Default
project = lowercase(project)
return GetIni('Project:' Project, Key, Default)
GetIniFile: procedure
/**
*** This will find the INI file that contains profile information.
**/
/* Look for an environment variable first */
IniFile = value('Hilbert.Ini',,"OS2ENVIRONMENT")
if IniFile = '' then
IniFile = SysSearchPath("DPATH","Hilbert.Ini")
if IniFile = '' then
do
This = ThisDirectory()
if Exists(This"\Hilbert.Ini") then
IniFile = This"\Hilbert.Ini"
end
if IniFile = '' then
call Error 2002,1,"Hilbert.Ini"
return IniFile
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Changed Subroutines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
Changed: procedure expose IniFile
/**
*** 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 */
TempFile = GetIni('File','Temp Changed','c:\temp.1')
'@erase' TempFile '> nul'
ReportFile = Open(TempFile '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 */
Editor = GetIni('Program','Editor','e.exe')
'@'Editor TempFile
return
ChangedDirectory: procedure expose IniFile Report.
/**
*** 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
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
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ "To-Be" Included routines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
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
GetLibpath: procedure
/**
*** This will return the LIBPATH string
**/
Boot = SystemDrive()
call SysFileSearch 'LIBPATH=', Boot':\CONFIG.SYS', 'Libpath','N'
select
when Libpath.0 = 0 then
Idx = 0
when Libpath.0 = 1 then
parse var Libpath.1 Idx Dlls
otherwise
do
Dlls = ''
do j = 1 to Libpath.0
parse upper var Libpath.j Idx Path .
if left(Path,8) = 'LIBPATH=' then
Idx = j
end
end
end /* select */
if Idx = 0 then
Dlls = 0
else
do
/* Get the "Idx'th" line */
Config = Open(Boot':\CONFIG.SYS','Read')
do i = 1 to Idx-1
code = LineIn(Config)
end
Dlls = LineIn(Config)
Config = Close(Config)
end
return substr(Dlls, 9) /* Remove the "LIBPATH=" */
/**
*** ┌──────────────────────────────────────────────────────────────────────┐
*** │ Included routines │
*** └──────────────────────────────────────────────────────────────────────┘
**/
/* #include LoadFunctions.rex */
LoadFunctions: procedure
/**
*** This will load the DLL for the Rexx system functions supplied
*** with OS/2 v2.0
**/
call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
call SysLoadFuncs
return
/* #include <error.rex> */
/**
*** ╔═══════════════════════════════════════════════════════════════════════╗
*** ║ Error Handler ║
*** ╚═══════════════════════════════════════════════════════════════════════╝
**/
Error: procedure
/**
*** This is a centralized processor for error messages and error handling
**/
parse arg ErrNo,Fatal,String1,String2,String3
if Fatal = 0 then
MsgId = 'HRX'right(ErrNo,4,"0")'W:'
else
MsgId = 'HRX'right(ErrNo,4,"0")'E:'
/* Select the error string based on the error number */
select
when ErrNo = 0 then return
when ErrNo = 1001 then Msg = "Return code %1 from RxFuncAdd for SQLEXEC"
when ErrNo = 1002 then Msg = "Return code [%1] from SQLEXEC. You are probably out-of-storage."
when ErrNo = 1003 then Msg = "SQL code [%1]: %2"
when ErrNo = 2002 then Msg = "File '%1' not found."
when ErrNo = 2003 then Msg = "Directory '%1' doesn't exist."
when ErrNo = 2004 then Msg = "Missing parameter. %1"
when ErrNo = 2005 then Msg = "Close failure on %1. %2"
when ErrNo = 2006 then Msg = "Open failure on %1. %2"
when ErrNo = 2007 then Msg = "Invalid parameter %1. %2"
when ErrNo = 2008 then Msg = "Environment variable %1 is not set. %2"
when ErrNo = 3000 then Msg = "Urecognized message '%1' passed from message queue."
when ErrNo = 3001 then Msg = "Error from server: %1."
when ErrNo = 3002 then Msg = "Invalid keyword: %1. %2"
when ErrNo = 3003 then Msg = "File %1 is not of the proper format."
when ErrNo = 3100 then Msg = "No matching object found %1"
when ErrNo = 4000 then Msg = "Host screen doesn't match expected value of '%1'"
when ErrNo = 4001 then Msg = "Unexpected return code '%1' from HLLAPI verb '%2'"
when ErrNo = 4800 then Msg = "NetBIOS '%1' received a return code %2"
when ErrNo = 5005 then Msg = "Return code 5 from RxQueue. Not a valid queue name: '%1'"
when ErrNo = 5009 then Msg = "Return code 9 from RxQueue. Queue does not exist: '%1'"
when ErrNo = 5010 then Msg = "Return code 10 from RxQueue. Queue is busy: '%1'"
when ErrNo = 5012 then Msg = "Return code 12 from RxQueue. Memory failure on queue: '%1'"
when ErrNo = 6000 then Msg = "Return code 1000 from RxQueue. Initialization error on queue: '%1'"
when ErrNo = 9999 then Msg = "%1"
otherwise Msg = "[%1,%2,%3]"
end /* select */
/* Render the string with the substituted parameters */
Msg = ErrorRender('%1',String1,Msg)
Msg = ErrorRender('%2',String2,Msg)
Msg = ErrorRender('%3',String3,Msg)
Callback = value("REXX.CALLBACK",,"OS2ENVIRONMENT")
if Callback = '1' then
call ErrorHandler Msg
else
say MsgId Msg
/* Should we terminate? */
if Fatal then exit ErrNo
return 0
ErrorRegister: procedure
/**
*** This will register a callback to the calling routine for error handling
*** after the error message has been rendered.
***
*** If this code is called, the caller MUST have a routine called
*** 'ErrorHandler' that is used to display the error message in an
*** appropriate way.
***
**/
parse arg callback
if callback = '' then
callback = '1'
code = value("REXX.CALLBACK",callback,"OS2ENVIRONMENT")
return 0
ErrorRender: procedure
parse arg Symbol,SymValue,Line
if pos(Symbol, Line) > 0 then
do
parse var Line prefix (Symbol) suffix
Line = prefix || SymValue || suffix
end
return Line
/* #include <system.rex> */
/**
*** ┌───────────────────────────────────────────────────────────────────────┐
*** │ Misc system functions │
*** └───────────────────────────────────────────────────────────────────────┘
**/
ThisDirectory: procedure
/**
*** This will return the directory from which this exec was run
**/
parse source . . ThisFile
LastSlash = lastpos('\', ThisFile)
ThisDir = left(ThisFile, (LastSlash-1))
return ThisDir
SystemDirectory: procedure
/**
*** This will try to determine where the OS/2 system is located by
*** looking for a key DLL
**/
dir = "C:\OS2"
code = RxQueue('Create','SysDir')
que = RxQueue('Set' ,'SysDir')
'@pstat /L | rxqueue SysDir'
do while queued() > 0
pull line
if pos('DOSCALL1.DLL', line) > 0 then
do
line = word(line, words(line))
parse var line dir '\DLL\DOSCALL1.DLL'
do queued();pull .;end
end
end
code = RxQueue('Delete','SysDir')
que = RxQueue('Set' ,que)
return strip(dir)
SystemDrive: procedure
/**
*** This will return the single drive letter for the system
**/
path = translate(value("PATH",,"OS2ENVIRONMENT"))
psn = pos(":\OS2",path)
if psn < 1 then
BootDrive = 'C'
else
BootDrive = substr(path,(psn-1),1)
return BootDrive
WaitOnProcess: procedure
/**
*** This will wait until the process count for the process name
*** passed is less than or equal to the count passed. There is
*** also an optional polling wait time.
**/
arg process,count,wait
if count = '' then
count = 0
if wait = '' then
wait = 15 /* Default to polling every 15 seconds */
QName = RxQueue('Create')
Prev = RxQueue('Set',QName)
do until found <= count
call SysSleep wait
'@pstat /c | RXQUEUE' QName
found = 0
do queued()
pull pstat
if pos(process,pstat) > 0 then
found = found + 1
end
end
code = RxQueue('Set',Prev)
code = RxQueue('Delete',QName)
return 0
ScanEnvironment: procedure expose IniFile
/**
*** 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
**/
parse arg EnvVariable, File
EnvVariable = translate(EnvVariable)
if EnvVariable = '' then
do
call Error 2004,0,"You must specify the environment variable."
return
end
if File = '' then
do
call Error 2004,0,"You must specify the filename to search for."
return
end
/* Take care of the special case for LIBPATH */
if EnvVariable = 'LIBPATH' then
do
EnvValue = GetLibpath()
code = value("LIBPATH",EnvValue,"OS2ENVIRONMENT")
end
select
when EnvVariable = 'PATH' then extensions = 'COM EXE BAT CMD'
when EnvVariable = 'DPATH' then extensions = 'DAT MSG'
when EnvVariable = 'LIBPATH' then extensions = 'DLL FON'
when EnvVariable = 'HELP' then extensions = 'HLP INF'
when EnvVariable = 'BOOK' then extensions = 'INF'
when EnvVariable = 'BOOKSHELF' then extensions = 'INF'
when EnvVariable = 'READIBM' then extensions = 'BOO'
when EnvVariable = 'BOOKMGR' then extensions = 'BOO'
otherwise extensions = ''
end
fspec = SysSearchPath(EnvVariable, file)
do i = 1 to words(extensions) while(fspec = '')
ext = word(extensions, i)
fspec = SysSearchPath(EnvVariable, file'.'ext)
end
return fspec
/* #include <filesystem.rex> */
CompareFileTimes: procedure
/**
*** This returns a boolean that indicates if the datetime stamps from
*** first file is older than the datetime stamp from the second file.
*** the file formats are the syntax from the SysFileTree
**/
parse arg Stamp.1, Stamp.2
do i = 1 to 2
parse var Stamp.i mon '/' day '/' year hour ':' temp
parse var temp min 3 meridian
hour = right(hour,2,'0')
mon = right(mon,2,'0')
CompareStamp.i = year||mon||day||meridian||hour||min
end
select
when CompareStamp.1 < CompareStamp.2 then
return '<'
when CompareStamp.1 > CompareStamp.2 then
return '>'
otherwise
return '='
end /* select */
return '='
QualifiedDirectory: procedure
/**
*** This determines if the file passed is a directory
**/
parse arg DirSpec
Current = directory() /* Save current directory */
NewDir = directory(DirSpec) /* Get the fully qualified name */
Current = directory(Current) /* Restore directory */
return NewDir
RootName: procedure
/**
*** This will return the root name (e.g. the file name without the
*** extension) for the filename passed
**/
parse arg File
parse value FileSpec("name",File) with ReturnName "." .
return ReturnName
/* #include <io.rex> */
Close: procedure
/**
*** Close a file I/O stream
**/
parse arg file
if file = '' then
do
call Error 2005,1,file,"No file name was passed to the CLOSE routine."
return
end
message = stream(file,c,'CLOSE')
if (message <> 'READY:') & (message <> '') then
call Error 2005,1,file,message
return file
Exists: procedure
/**
*** Return a Boolean indicating whether the file exists or not
**/
arg file
file = stream(file,c,'QUERY EXIST')
if (file = '') then
return 0
else
return 1
Open: procedure
/**
*** Open a file for READ, WRITE, APPEND or RANDOM (read/write)
**/
parse arg file, rw
if file = '' then
do
call Error 2006,0,file,'No file name passed on OPEN call.'
return ''
end
rw = translate(rw)
select
when rw = 'WRITE' then
do
file_ = stream(file,c,'QUERY EXIST')
if file_ <> '' then
'@erase "'file'" 2> NUL'
end
when rw = 'APPEND' then
rw = 'WRITE'
when rw = 'READ' then
rw = 'READ'
when rw = 'RANDOM' then
rw = ''
otherwise
rw = 'READ'
end /* select */
message = stream(file,c,'OPEN' rw)
if (message \= 'READY:') then
do
call Error 2006,0,file,message
return ''
end
return file
/* #include <string.rex> */
MapSymbol: procedure
/**
*** This will translate the input string to the output string.
**/
parse arg string, in, out
outstring = ''
psn = pos(in, string)
do while(psn > 0)
if psn > 1 then
outstring = outstring || substr(string, 1, psn-1)
outstring = outstring || out
string = substr(string, psn+length(in))
psn = pos(in, string)
end
outstring = outstring || string
return outstring
UpperCase: procedure
/**
*** This will convert the string to uppercase
**/
parse upper arg string
return string
GetNoEcho: procedure
/**
*** This will grab keystrokes and enter them back as '*' characters
**/
Password = ''
Key = SysGetKey('NoEcho')
do while c2x(Key) <> '0D'
select
when c2x(Key) = '08' then
Password = left(Password, (length(password)-1))
otherwise
Password = Password || Key
end /* select */
Key = SysGetKey('NoEcho')
end
return Password
LowerCase: procedure
/**
*** This will return the string passed after converting it to lowercase
**/
parse arg String
String = translate(String, "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
return String
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
/* #include <parseopt.rex> */
ParseOptions: procedure expose Opt.
/**
*** This will parse the string passed into option flags and positional
*** parameters. Flags are delimited by slash (/) or dash (-). Positional
*** parms are all the rest with leading and trailing blanks removed
**/
Opt.Parm.0 = 0
parse arg optstring
do while (optstring \= '')
optstring = strip(optstring)
parse value ParseOptTokenType(optstring) with TokenType optstring
if TokenType = 'F' then
do
parse var optstring fl 2 optstring
fl = ParseOptSwitch(fl)
parse value ParseOptValue(optstring) with col optstring
if col = 0 then
FlagValue = ""
else
parse var optstring FlagValue +(col) optstring
Opt.Flag.fl = FlagValue
end
else
do
parse value ParseOptValue(optstring) with col optstring
if col = 0 then
ParmValue = ""
else
parse var optstring ParmValue +(col) optstring
j = Opt.Parm.0 + 1
Opt.Parm.j = ParmValue
Opt.Parm.0 = j
end
end /* while */
return 0
ParseOptValue: procedure
/**
*** This will parse a value, properly handling quoted strings. It
*** returns the split column followed by the option string (possibly
*** with extraneous quotes removed
**/
parse arg optstring
FirstChar = left(optstring, 1)
if FirstChar = " " then
return 1 "+"optstring
if (FirstChar = '"') | (FirstChar = "'") | (FirstChar = '`') then
do
parse var optstring quote 2 optstring
ending = pos(quote, optstring)
select
when ending = 0 then
return length(optstring) optstring
when ending = 1 then
return 0 substr(optstring,2)
otherwise
ending = ending - 1
end /* select */
parse var optstring ParmValue +(ending) quote +1 Remain
return length(ParmValue) ParmValue || Remain
end
else
do
parse var optstring ParmValue Remain
return length(ParmValue) ParmValue || Remain
end
return 0
ParseOptTokenType: procedure
/**
*** This will determine the token type and return the remainder of the
*** string to be parsed.
**/
parse arg optstring
FirstChar = left(optstring,1)
select
when FirstChar = '-' then
do
TokenType = 'F'
Remain = substr(optstring,2)
end
when FirstChar = '/' then
do
TokenType = 'F'
Remain = substr(optstring,2)
end
otherwise
do
TokenType = 'P'
Remain = optstring
end
end /* select */
return TokenType Remain
ParseOptSwitch: procedure
/**
*** This translates the flag into an symbolic
**/
arg FlagName
if ((FlagName < 'A') | (FlagName > 'Z')) then
do
select
when FlagName = '?' then FlagName = 'SYNTAX'
when FlagName = '!' then FlagName = 'BANG'
when FlagName = '*' then FlagName = 'STAR'
when FlagName = '#' then FlagName = 'POUND'
when FlagName = '$' then FlagName = 'DOLLAR'
when FlagName = '%' then FlagName = 'PERCENT'
when FlagName = '^' then FlagName = 'HAT'
when FlagName = '&' then FlagName = 'AMP'
when FlagName = '(' then FlagName = 'LPAR'
when FlagName = ')' then FlagName = 'RPAR'
when FlagName = '-' then FlagName = 'DASH'
when FlagName = '=' then FlagName = 'EQUAL'
otherwise /* Force a syntax message */
FlagName = 'SYNTAX'
end /* select */
end /* if */
return FlagName
/* #include <misc.rex> */
MakeFileName: procedure
/**
*** This will make a file name from the string passed. In the case of
*** HPFS, the name is left pretty much alone. In the case of FAT, the
*** 1st 8 chars are returned, which has a good chance of not being
*** unique.
**/
parse arg FileSystem,string
string = strip(string)
if FileSystem = 'HPFS' then
Name = translate(string, '!!...!---+', '"\/:*?|<>-&')
else
Name = left(translate(string, '___________', '"\/:*?|<>-&'), 8)
return Name
GetHilbertIni: procedure
/**
*** This will find the INI file that contains profile information.
**/
/* Look for an environment variable first */
IniFile = value('Hilbert.Ini',,"OS2ENVIRONMENT")
if IniFile = '' then
IniFile = SysSearchPath("DPATH","Hilbert.Ini")
if IniFile = '' then
do
This = ThisDirectory()
if Exists(This"\Hilbert.Ini") then
IniFile = This"\Hilbert.Ini"
end
if IniFile = '' then
call Error 2002,1,"Hilbert.Ini"
return IniFile
GetTechServIni: procedure
/**
*** This will find the INI file that contains profile information.
**/
/* Look for an environment variable first */
IniFile = value('TechServ.Ini',,"OS2ENVIRONMENT")
if IniFile = '' then
IniFile = SysSearchPath("DPATH","TechServ.Ini")
if IniFile = '' then
do
This = ThisDirectory()
if Exists(This"\TechServ.Ini") then
IniFile = This"\TechServ.Ini"
end
if IniFile = '' then
call Error 2002,1,"TechServ.Ini"
return IniFile
GetUniqueKey: procedure
/**
*** This will return a unique numeric key to the caller. This should be
*** a systemwide critical section, but there's no way to do that in
*** standard REXX, so we will hope for the best.
**/
parse arg IniFile
IniValue = SysIni(IniFile,'Global','Unique Key')
if datatype(IniValue,'Numeric') <> 1 then IniValue = 0
IniValue = IniValue + 1
code = SysIni(IniFile,'Global','Unique Key',IniValue)
return IniValue
Pause: procedure
/**
*** This will wait for a keystroke
**/
parse arg prompt
if prompt <> '' then
call charout ,prompt
Key = SysGetKey('NOECHO')
return Key
GetIni: procedure expose IniFile
/**
*** This will pull a value from the INI file or the default value if
*** there is no entry in the INI file.
**/
parse arg Application, Key, Default
IniValue = SysIni(IniFile,Application,Key)
if IniValue = 'ERROR:' then
do
say "Enter value for"
say " Application: '"Application"'"
say " Key: '"key"'"
say " Default: '"Default"'"
call charout ,"> "
parse pull IniValue
if IniValue = '' then
do
IniValue = Default
if IniValue <> '' then
code = SysIni(IniFile,Application,IniValue)
end
code = SysIni(IniFile,Application,Key,IniValue)
end
return IniValue
/**
*** ═══════════════════════════════════════════════════════════════════════
*** Change History:
*** 3.0 - Changed to use INI services. Removed some rarely-used
*** routines. Changed code to use the preprocessor and common
*** included code.
*** 3.1 - Prompt for INI information on 'ERROR:'.
*** 3.2 - Added RECURSE
*** Changed the INCLUDE env var for IBMC profile
*** 3.3 - Added COPYSAFE to the code
*** 3.4 - Added BACKUP CONFIG and BACKUP CHRON
*** 3.4.1 - Fixed bug where INIFILE wasn't exposed properly for BACKUP
*** subcommand.
*** 3.4.2 - Fixed a bug on the copy command when the second dest parm
*** was omitted.
*** 3.5 - Added TRACE command
*** Added SCANENVIRONMENT command
*** 3.5.1 - Made WHICH an alias for SCANENVIRONMENT
*** Added automatic extension searching on WHICH based on the
*** environment variable.
*** 3.6 - Changed ZIP function to use project profiles
*** - Added more to PROFILE to work with make and eliminate
*** NMAKEPTH.INC.
*** 3.7 - Tweaked MAKE and PROFILE functions
*** 3.8 - More work on PROFILE commands
*** 3.9 - Added support for additional LIB paths and INCLUDE paths
*** to the profile.
*** 3.10 - Misc bug fixes
*** 3.11 - Added the LIB function
*** 3.12 - Added the code to verify the Gopher menus
*** 3.13 - Changed PROFILE IBMCPP to include Hilbert classes
*** 3.14 - Changed notification process to NOT issue a start, but
*** to invoke the program directly
*** 3.15 - Added LIB MAKE
*** - Added SYNCH code
*** 3.16 - Added SYNCH C++
*** - Fixed a bug where copysafe was exiting instead of returning
*** - PROFILE creates base directory if it didn't exist
*** ═══════════════════════════════════════════════════════════════════════
**/