tldm-universe/Ardent/UV/APP.PROGS/VMADMSUB.B
2024-09-09 17:51:08 -04:00

12885 lines
414 KiB
Brainfuck
Executable File

*******************************************************************************
*
* Server subroutine for graphical administration client
*
* Module %M% Version %I% Date %H%
*
* (c) Copyright 1998 Ardent Software Inc. - All Rights Reserved
* This is unpublished proprietary source code of Ardent Software Inc.
* The copyright notice above does not evidence any actual or intended
* publication of such source code.
*
*******************************************************************************
*
* Maintenence log - insert most recent change descriptions at top
*
* Date.... GTAR# WHO Description........................................
* 08/12/99 24446 SAP Port Linux to 9.5.1
* 05/18/99 24138 OGO Add account based file loading for performance
* 05/10/99 24138 OGO Fix rep ID integer overflow problem
* 04/28/99 24138 OGO Replication admin rewrite
* 04/28/99 23626 OGO Account publish and subscribe support
* 04/28/99 24139 OGO Add new UDR debug config parameter
* 04/28/99 24140 OGO Add new UDR logoldest config parameter
* 04/28/99 23663 OGO return Error for unsupported file revisions
* 04/28/99 23641 OGO Dictionary publish and subscribe support
* 04/28/99 21797 OGO Add Distributed file support
* 01/15/99 21797 OGO Add File type display support to publish and subscribe lists.
* 01/14/99 21797 OGO Add support to Replication for explicite file paths,
* Q-Pointers, and Multi-level files. Add more comments
* 11/23/98 23768 DJD Fixed build for last fix.
* 11/19/98 23768 DJD Check for bad accounts.
* 11/09/98 23768 WSM Assign Error after successful RPC.CALL in Diag routines.
* 11/03/98 23768 DJD Filetool fixes.
* 10/19/98 23768 DJD Added support for file fix tool.
* 10/14/98 23801 SAP Change copyrights.
* 07/15/98 23388 RJE Added code for new Network Services routines to
* maintain user login account information.
* 06/26/98 23161 RGA Add support for 'raw' device trans. logging
* 01/23/98 22499 RJE Fixed OSBrowse when given directories with spaces.
* 12/12/97 22338 OGO Changed RepFailOver,GetRepSystemNames
* 12/12/97 22257 OGO Changed GetRepSystems
* 10/25/97 20606 OGO Fixed number of replication admin problems.
* 10/17/97 20606 OGO Fixed file merge error.
* 10/15/97 20606 DJD Finished replication.
* 07/29/97 20246 DJD Fixed message in DELREMSUB
* 07/29/97 20246 DJD Added various fixes for replication
* 07/10/97 20246 DJD Added replication services.
* 03/12/97 20246 DJD Added DataSource and DeadLock management
* 10/18/96 19474 JC Check and report error for non-existant backup
* target path.
* 09/30/96 19347 LA Don't allow TL to be enabled if it is already
* on its way up
* 09/27/96 19329 LA LISTU output format has changed - change the parsing
* 09/27/96 19338 JC Fix PrintedAt to handle large activity log.
* 09/19/96 19281 RKM Fixed OSBrowse when given empty drives/invalid
* pathnames on NT.
* 09/19/96 19274 JC Get BLKMAX from uvconfig parameters.
* 09/17/96 19252 JC Ensure all 'cd's are 'cd /d' on NT
* 09/06/96 19194 ALC Make handling of &PARTFILE& IDs cas insensitive on NT
* 09/05/96 19186 JC Check id PORT.STATUS is in use by other process.
* 08/16/96 19074 JC Add check for warning from RECOVERY.CHECKPOINT
* 08/16/96 19076 JC Use usd -V to check if the spooler is running.
* 08/14/96 19058 JC Fix use of command line separators on NT.
* 08/08/96 19023 JC Allow transction logging on files with & in them.
* 08/07/96 18952 LA Use access to check for existance of SHM.TO.LOAD
* 08/06/96 18985 JC Remove -a option from Mag/Account Restore on NT
* 07/31/96 18945 JC Re-create sp.config file if it doesn't exist.
* 07/23/96 18890 LA Change the way CheckAccountDir works so that it
* checks both the directory and the VOC file.
* 07/18/96 18873 JC Added return flag for is tranaction logging info
* file has been truncated to 16k. Also extended all
* information file returns to 16k
* 07/12/96 18830 JC Add support for IN2 import on NT.
* 07/11/96 18809 JC Fixed defer times for print jobs.
* 07/03/96 17839 LA Various fixes including removing CheckAndRelease
* and returning UVHome & OSExec from Initialise.
* Removed DeleteSynonymAccs.
* 02/08/96 17839 JC Change UniVerseBrowse to only return local files.
* 07/02/96 17839 LA Changed location of include files
* 07/01/96 17839 LA Add extra transaction logging functions
* 06/28/96 17839 PGW Fixed various problems with OSBrowse
* 06/13/96 17839 LA Add import account functions
* 05/24/96 17839 PGW Add functions for Backup/Restore
* 05/17/96 17839 LA Add user admin. code & use INTERNAL keyword to
* LIST.READU
* 04/22/96 17839 LA Add transaction logging code, change ListLocks
* to use INTERNAL keyword to list_readu and fix
* OSBrowse to work with NT
* 04/02/96 17839 LA Add device admin code.
* 03/18/96 17839 LA Add network services code and check to ensure
* important directories cannot be deleted. Also
* made sure that code which is only relevent to
* unix has os specific markers round it.
* 03/11/96 17839 LA Add account admin. code. Get UVHOME
* using system(32). Use OS.EXEC in ShellCommand
* 02/27/96 17839 LA Add config editor code
* 02/14/96 17839 LA Add uniVerse command execution code
* 02/05/96 17839 LA Add lock administration code
* 01/08/96 17839 LA Add Shared memory code
* 11/07/95 17839 LA Subroutine created
************************************************************************
*
* DESCRIPTION:
*
* This subroutine contains all the server code for the graphical
* uniVerse administration tool.
*
* Input arguments: Action - key for action to be taken
* Params - parameters required by the
* particular function being
* performed, field mark separated
*
* Output arguments: OutData - any output from the requested
* function, field mark separated
* Error - error code or 0 if no error
*
* NOTE: This module has had all unused subs stripped out of it. Add them
* back in as necessary from vmadmsub.complete
*
* Actions for each admin area should be grouped together (eg. Device
* maintenance uses codes 21 - 30) and subroutines should be added in
* alphabetical order for easier maintenance.
*
************************************************************************
SUBROUTINE (AdminCode, Params, OutData, Error)
$INCLUDE UNIVERSE.INCLUDE MACHINE.NAME
$INCLUDE UNIVERSE.INCLUDE TLOG.H
$INCLUDE UNIVERSE.INCLUDE VMADMERR.H
$INCLUDE UNIVERSE.INCLUDE VMADMCMN.H
$INCLUDE UNIVERSE.INCLUDE UDR.INCLUDE.H
$INCLUDE UNIVERSE.INCLUDE FILEFIX.INCLUDE.H
DEFFUN UVREADMSG(num, args) CALLING '*UVREADMSG'
DEFFUN IsFullPath(a) CALLING '*IS.FULLPATH'
DECLARE GCI access
DECLARE GCI UDRgetheaderinfo
DECLARE GCI UDRsetheaderinfo
DECLARE GCI UDRsetshmmessage
EQU Text To Out ; * Horrible hack
EQU CRLF To Char(13):Char(10)
EQU CR To Char(13)
EQU TAB To Char(9)
EQU DEFPERMS To 777 ; * Default permissions
EQU SHM.TO.LOAD To "SHM.TO.LOAD"
EQU UVCONFIG To "uvconfig"
EQU GROUPLOCK To 1 ; * Used by lock admin.
EQU RECORDLOCK To 2 ; * Used by lock admin.
EQU FILELOCK To 3 ; * Used by lock admin.
EQU TEMPREC To "VMUVADTMP" ; * Temporary record name
* Layout of config files:
EQU INITIAL$PATTERN TO '"####"0X' ; * end of copyright section
EQU COMMENT$PATTERN TO '"#"0X' ; * general comment introducer
EQU COMMENT$CHAR TO '#'
* Set up array containing paths which MUST NOT be deleted
EQU DONOTDELETE To '/':@FM:'/bin':@FM:'/usr/bin':@FM:'/usr/sbin':@FM:'/etc':@FM:'/dev':@FM:'/usr'
* Set up defaults for telnet data (NT only)
EQU DFLT.TELNETPORT To "23"
EQU DFLT.MAXLOGON To "4"
EQU DFLT.LOGONPAUSE To "4"
EQU DFLT.LOGONTIMEOUT To "30"
EQU DFLT.TERMPAUSE To "4"
EQU DFLT.USERPOLICY To "1"
EQU WINERR.NOREGENTRY To 2 ; * Registry entry not found
* Equates for access keys
EQU F$OK To 0 ; * File exists
EQU X$OK To 1 ; * Execute access
EQU W$OK To 2 ; * Write access
EQU R$OK To 4 ; * Read access
* List of &DEVICE& codes which specify tape devices:
EQU TAPE.DEVICE.PATTERN To "'DT'":@VM:"'DC'":@VM:"'T'":@VM:"'C'"
* Set up arrays for printer definitions (unix). These are used to
* parse the sp.config printer entries
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
scratch = UVREADMSG(073336, "")
baud.array = ""
baud.array<1> = scratch<10> ; * 75
baud.array<2> = scratch<11> ; * 110
baud.array<3> = scratch<12> ; * 134.5
baud.array<4> = scratch<13> ; * 150
baud.array<5> = scratch<14> ; * 300
baud.array<6> = scratch<15> ; * 600
baud.array<7> = scratch<16> ; * 1200
baud.array<8> = scratch<17> ; * 1800
baud.array<9> = scratch<18> ; * 2400
baud.array<10> = scratch<19> ; * 4800
baud.array<11> = scratch<20> ; * 9600
baud.array<12> = scratch<21> ; * 19200
parity.array = ""
parity.array<1> = scratch<23> ; * NONE
parity.array<2> = scratch<24> ; * EVEN
parity.array<3> = scratch<25> ; * ODD
cr.array = ""
cr.array<1> = ""
cr.array<2> = "ONLCR"
cr.array<3> = "ONCRNL"
cr.array<4> = "ONOCR"
End
************************
* OS specific code end *
************************
* Set up pathname and command separators for this operating system. If
* this becomes available in MACHINE.NAME, remove this code
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
OS.SEP = "/"
OS.CMDSEP = ";"
OS.CD = "cd "
End Else
OS.SEP = "\"
OS.CMDSEP = " && "
OS.CD = "cd /d "
End
************************
* OS specific code end *
************************
OutData = ""
Error = 0
AdminCode += 1
KeepFileOpen = False
UnixFileOpen = False
* Set NLS mapping for reading os files
If System(100) Then
Execute "SET.SEQ.MAP OS" Capturing Out
End
* Set Replication version information
* the client version will change when "RepVersionInfo" is called
RepAdminClientVersion = "3"
RepServerVersion = "3"
If DEBUGGING Then
LogText = "ClientAdminCode = ":AdminCode - 1:" OnGosubIndex = ":AdminCode
Gosub WriteDbg
LogText = "Params = ":Change(Params, @fm, "^]")
Gosub WriteDbg
End
**********************************************************************
* Gosub based on AdminCode
*
* Grouping is:
*
* 1 - 20 Miscellaneous
* 21 - 30 Device Maintenance
* 31 - 40 Account Maintenance
* 41 - 50 Catalog shared memory
* 51 - 70 Spooler
* 71 - 80 Config Editor
* 81 - 90 User administration
* 91 - 100 Lock administration
* 101 - 110 UniVerse Command
* 111 - 120 Network Services
* 121 - 140 Transaction logging
* 141 - 150 Backup/Restore
* 151 - 160 Import account
* 161 - 170 Deadlock Manager
* 171 - 180 ODBC Data Sources
* 181 - 210 Replication
* 211 - 230 Fix File Tool
*
*********************************************************************
On AdminCode Gosub Initialise,
OSBrowse, ; * 1
UniVerseBrowse,
GetMachineType, ; * Temporary
GetDrives,
GetUVHome,
GetAccountPath,
GetFilePath,
Unused,
Unused,
Unused,
Unused, ; * 11
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
DeviceList, ; * 21
GetMaxBlockSize,
GetDevice,
PutDevice,
DeleteDevice,
TapeTest,
GetNLSMaps,
EnumPrinters,
Unused,
Unused,
AccountList, ; * 31
UserList,
GroupList,
DeleteAccount,
MakeAccount,
AccountDets,
ChangeAccount,
CheckAccountDir,
Unused,
Unused,
ShmLoad, ; * 41
ShmModify,
ShmRunning,
ShmGetProgSize,
ShmWriteSHMTOLOAD,
ShmListSHMTOLOAD,
ShmReleaseLock,
Unused,
Unused,
Unused,
SpoolPrinterDets, ; * 51
GetSpoolConfig,
SpoolContinue,
SpoolSuspend,
SpoolJobControl,
SpoolPrintedAt,
SpoolMount,
SpoolErrorLog,
SpoolActivityLog,
ResetSpooler,
StartSpooler, ; * 61
StopSpooler,
ModSpoolJob,
JobDets,
SetSpoolConfig,
CancelSpoolConfig,
EnablePrinting,
AllowQueueing,
GetPrinterGroups,
SetPrinterGroup,
GetUVConfig, ; * 71
SetUVConfig,
DBSetup,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
Users, ; * 81
Logout,
Message,
MessUsers,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
ListLocks, ; * 91
ReleaseLock,
ReleaseUserLocks,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
SaveUVCommand, ; * 101
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
GetRPCInfo, ; * 111
SetRPCPort,
SaveNodes,
NetReleaseLocks,
GetTelnetInfo,
SetTelnetInfo,
GetUserInfo,
DeleteUserInfo,
GetUserInfoDetails,
UpdateUserInfoDetails,
GetLoggingState, ; * 121
LogFileInfo,
LogControl,
ViewInfoFile,
DeleteInfoFile,
SetLoggingConfig,
ListActiveFiles,
SetActiveFiles,
SetLogFiles,
ReleaseLogFiles,
PurgeLogFiles, ; * 131
GetTransferLogs,
ChangeToFiles,
IdentifyLogs,
ClearFlag,
RollFwdToFile,
Unused,
Unused,
Unused,
Unused,
GetLocalAccountPaths, ; * 141
CheckDirectoryPath,
CheckBackupTarget,
Unused,
RemoveBackupTarget,
GetAccountFiles,
CheckRestoreSource,
ParseRestoreLabel,
Unused,
Unused,
MagrstCommand, ; * 151
AcctrstCommand,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
GetDeadLockConfig, ; * 161
GetDeadLockState,
ListDeadLocks,
StartDeadLocking,
StopDeadLocking,
SaveDeadLockConfig,
PurgeDeadLockLog,
ExamineDeadLockLog,
ResolveDeadLock,
Unused,
GetDataSources, ; * 171
GetDataSourceEntry,
UpdateDataSourceEntry,
DeleteDataSourceEntry,
CreateDataSourceEntry,
Unused,
Unused,
Unused,
Unused,
Unused,
RepGetState, ; * 181
RepGetReplicationConfig,
RepSaveReplicationConfig,
RepControl,
RepExamineRepLog,
RepClearRepLog,
RepPublishFile,
RepUnPublish,
RepGetPublishedFiles,
RepGetPublishedFileDetails,
RepUpdatePublishedFile, ; * 191
RepSubscribeFile,
RepUnSubscribe,
RepGetSubscriptions,
RepGetSubscriptionDetails,
RepUpdateSubscription,
RepGetSystems,
RepGetSystemDetails,
RepAddSystem,
RepUpdateSystem,
RepDeleteSystem, ; * 201
RepGetSystemNames,
RepGetRemotePubs,
RepRemoveRemoteSub,
RepResumeLogManager,
RepFailOver,
RepAccountList,
RepGetUVFiles,
RepVersionInfo,
RepRepairFile,
GetFilesWithDetails, ; * 211
GetMultiLevelFiles,
GetMultiLevelFilesWithDetails,
GetFileDetails,
SetupDiagnosicsRun,
ShutdownDiagnosicsRun,
DiagPhysicalStructure,
DiagFileHeader,
DiagFileGroups,
DiagFileData,
DiagFileMisc, ; * 221
GetFixErrors,
FixTheFile,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
Unused,
RepGetMultiLevelFiles, ; * 231 replication continued
RepGetMultiLevelFileParts
If DEBUGGING Then
LogText = "OutData = ":Change(OutData, @fm, "^]")
Gosub WriteDbg
LogText = "Error = ":Error
Gosub WriteDbg
End
RETURN
**********************************************************************
* AccountDets - Returns details of an account
*
* Input: Account name
* Output: Account path
* Account flavour
* Owner (null for NT)
* Group (null for NT)
* Permissions (null for NT)
**********************************************************************
AccountDets:
Path = ""
Flavor = ""
Owner = ""
Group = ""
Perms = ""
AccountName = Params<1>
Read AccountRec From UVACCOUNT, AccountName Else Return
Path = AccountRec<11>
FStat = ''
OpenSeq Path:OS.SEP:"VOC" To FL2 Then
Status FStat From FL2 Else FStat = ''
End Else
Error = EADM.NOACCOUNT
Return
End
Write "Q":@fm:AccountName:@fm:"VOC" On VOC, TEMPREC
Open TEMPREC To FL Then
ReadV Flavor From FL, "RELLEVEL",3 Else Flavor = ''
Close FL
End Else
Flavor = "UNKNOWN"
End
Delete VOC, TEMPREC
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
* User name: get directly from STATUS output
Owner = FStat<30>
* Group name: get group id from STATUS output and convert to group
* name
Group = FStat<9>
OpenSeq '/etc/group' To TFl Then
Found = 0
Loop
ReadSeq Line From TFl Else Line = ''
Until Found Or Status() Do
Found = ( Line[":",3,1] = Group )
If Found Then Temp = Line[":",1,1]
Repeat
CloseSeq TFl
If Found then Group = Temp
End
* Permissions: get Mode from STATUS output and convert to permissions
Mode = FStat<5>
Temp =Oconv(Mode,"MO")[3]
for I = 1 To 3
Text = Temp[I,1]
Begin Case
Case Text = 0
Perms := "---"
Case Text = 1
Perms := '--x'
Case Text = 2
Perms := '-w-'
Case Text = 3
Perms := '-wx'
Case Text = 4
Perms := 'r--'
Case Text = 5
Perms := 'r-x'
Case Text = 6
Perms := 'rw-'
Case Text = 7
Perms := 'rwx'
End Case
Next I
End ; * OS specific code
************************
* OS specific code end *
************************
OutData = Path:@vm:Flavor:@vm:Owner:@vm:Group:@vm:Perms
Return
**********************************************************************
* AccountList - Returns list of accounts on the server
*
* Input: NONE
* Output: Field mark separated list of account
* names
**********************************************************************
AccountList:
SSelect UVACCOUNT
Done = False
Loop
ReadNext Id Else Done = True
Until Done Do
OutData<-1> = Id
Repeat
Return
**********************************************************************
* AcctrstCommand - Set up command line for account.restore
*
* Input: Restore directory
* Device name
* Block size
* Use Type19 flag
* Flavour (P = PICK, M = Reality,
* I = IN800, J = IN500)
* Multi save flag (only used for Reality)
* Number of volumes (only used for IN500
* with tape type DC)
* Output: Command line
**********************************************************************
AcctrstCommand:
RstPath = Params<1>
DevName = Params<2>
BlockSize = Params<3>
Type19 = Params<4>
Flavour = Params<5>
MultiSave = Params<6>
NumVols = Params<7>
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
* Check that restore directory can be written to
If access(RstPath, W$OK + R$OK) Then
Error = EADM.NOACCESS
Goto ExitAcctrstCommand
End
End
************************
* OS specific code end *
************************
* Get device pathname from &DEVICE& file and check that the
* rewind device can be read from
Read DevRec From DEVICES, DevName Else
Error = EADM.CANTREAD
Goto ExitAcctrstCommand
End
DevPath = DevRec<2>
DevRewind = DevRec<6>
DevType = DevRec<4>
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
If access(DevRewind, R$OK) Then
Error = EADM.NOREADACCESS
Goto ExitAcctrstCommand
End
End
************************
* OS specific code end *
************************
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
ExLine = "ls -l " : DevPath
Gosub ShellCommand
If Out[1, 3] # "crw" Then
Error = EADM.BADDEVICE
Goto ExitAcctrstCommand
End
End
************************
* OS specific code end *
************************
Command = OS.CD
* Validation finished, set up the command line
Command := RstPath : OS.CMDSEP
If Flavour = "I" Or Flavour = "J" Then
* For IN5000 or IN8000 format tapes, we need to skip the
* headers
ForwardTape = DevRec<10>
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Command := " tape=" : DevPath : OS.CMDSEP
End
************************
* OS specific code end *
************************
Command := ForwardTape : OS.CMDSEP : ForwardTape : OS.CMDSEP
If Flavour = "J" And DevType = "DC" Then
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Command := UVHOMEBIN : "ddm " : NumVols
Command := " if=" : DevPath : " | "
End Else
Command := UVHOMEBIN : "uvmt "
Command := " -d" : DevPath
Command := " fread | "
End
************************
* OS specific code end *
************************
Command := UVHOMEBIN : "INfilter | "
Command := UVHOMEBIN : "acct.restore -i -"
Goto ExitAcctrstCommand
End
End
Command := " " : UVHOMEBIN : "tapein -ice"
Command := " -p" : UVHOMEBIN : "acct.restore"
Command := " -f" : DevPath
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Command := " -g" : DevRewind
End
************************
* OS specific code end *
************************
Command := " -b" : BlockSize
If Flavour = "I" Then
Command := " -i"
End Else
If Flavour = "M" Then
Command := " -m"
If MultiSave Then
Command := " -mas"
End
End
End
If Type19 Then
Command := " -t"
End
If DevType = "C" Or DevType = "DC" Then
Command := " -c"
End
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Command := " -a"
End
************************
* OS specific code end *
************************
ExitAcctrstCommand:
If Error = 0 Then
OutData = OS.EXEC : " " : Quote(Command)
End
Return
**********************************************************************
* AllowQueueing - Allows or disallows queueing on a printer
* Unix only.
*
* Input: Action: 0 - disallow queuing
* 1 - allow queueing
* Printername
* Output: NONE
**********************************************************************
AllowQueueing:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
GoSub CheckSpooler
If Error # 0 Then
Return
End
Key = Params<1>
PrinterName = Params<2>
If Key = 0 Then
ExLine = USA.PATH : " -q -p " : PrinterName
End Else
ExLine = USA.PATH : " +q -p " : PrinterName
End
GoSub ShellCommand
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* CancelSpoolConfig - Closes the uv.rc file if it is open
* Unix only
*
* Input: NONE
* Output: NONE
**********************************************************************
CancelSpoolConfig:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
If UVRC.OPEN Then
CloseSeq UVRC
End
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* ChangeAccount - Changes one or more attributes of an account
* If this is being used on an NT server, the
* only attribute which can be changed is the
* account name - all other parameters will
* be null.
*
* Input: Account name
* New account name or null
* Owner or null (unix only)
* Group or null (unix only)
* Use Default Perms or null (unix only)
* Permissions or null (unix only)
* Output: NONE
**********************************************************************
ChangeAccount:
AccountName = Params<1>
NewName = Params<2>
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
NewOwner = Params<3>
NewGroup = Params<4>
UseDfltPerms = Params<5>
NewPerms = Params<6>
End Else
NewOwner = ""
NewGroup = ""
UseDfltPerms = ""
NewPerms = ""
End
************************
* OS specific code end *
************************
If NewOwner <> "" or NewGroup <> "" Then
Params<1> = AccountName
Params<2> = NewOwner
Params<3> = NewGroup
Gosub ChownAcc
End
If UseDfltPerms <> "" Then
If UseDfltPerms = 1 Then
NewPerms = DEFPERMS
End
End
If NewPerms <> "" Then
Params<1> = AccountName
Params<2> = NewPerms
Gosub AccPerms
End
If NewName <> "" Then
Read AccRec From UVACCOUNT, AccountName Then
Delete UVACCOUNT, AccountName
Write AccRec To UVACCOUNT, NewName
End
End
Return
************************************************************************
* CheckAccountDir - Checks the state of an account with respect to
* the directory being deleted: finds out if there
* are any distributed files in the account; finds
* out if the account directory is a home directory
* for any users.
*
* If the account cannot be accessed (or does not
* exist), then an error will be returned together
* with the pathname of the account.
*
* Input: Account Name
* Output: Account Path
* PartFilesFlag (true if distributed files
* in the account)
* HomeDirFlag (true if directory is the
* home directory for any
* users) (unix only)
* Synonym accounts
* (list of UV.ACCOUNT entries
* which use the same directory,
* or null)
* User list (list of users for whom
* the directory is their
* home directory - only
* present if HomeDirFlag is
* true) (unix only)
************************************************************************
CheckAccountDir:
AccName = Params<1>
PartFlag = 0
HomeDirFlag = 0
UserList = ""
Readv AccPath From UVACCOUNT, AccName, 11 Else
Error = EADM.CANTREAD
Return
End
If Trim(AccPath) = "" Then
Error = EADM.BADPATH
Return
End
* First check that there is an accessible account in this directory
* - if there isn't, then the other things are irrelevant
AccVoc = AccPath : OS.SEP : "VOC"
If access(AccVoc, R$OK + W$OK) Then
* We don't have access, check if the VOC actually exists
Error = EADM.NOACCESS
If access(AccVoc, F$OK) Then
* VOC doesn't exist - check the directory
Error = EADM.BADACCOUNT
If access(AccPath, R$OK + W$OK) Then
* No access to directory, check if it exists
Error = EADM.NOACCESS
If access(AccPath, F$OK) Then
* No directory
Error = EADM.NODIRECTORY
End
End
End
OutData = AccPath
Return
End
* We can only get here if the account is accessible.
* Check if this account contains distributed files
**************************
* OS specific code start *
**************************
If OS.TYPE = "MSWIN" Then
Open "&PARTFILES&" TO Partfiles Else
Error = EADM.CANTOPEN
Return
End
UAccPath = Upcase(AccPath)
UAccPathLen = Len(UAccPath)
Select Partfiles To 1
Done = False
Loop
ReadNext Id From 1 Then
If Upcase(Id[1, UAccPathLen]) = UAccPath Then
Done = True
PartFlag = 1
End
End
Else
Done = True
End
Until Done
Repeat
ClearSelect 1
End
Else
ExLine = \SELECT &PARTFILES& WITH @ID LIKE "\:AccPath:\..."\
Gosub TCLCommand
NumIds = Field(Out, " ", 1)[2,1]
If NumIds > 0 Then
PartFlag = 1
End
End
************************
* OS specific code end *
************************
* Check if there are other accounts using this directory
SynonymAccs = ""
SSelect UVACCOUNT
Done = False
Loop
ReadNext Id Else Done = True
Until Done Do
If Id # AccName Then
ReadV Path From UVACCOUNT,Id,11 Else Path = ""
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
If Path = AccPath Then
SynonymAccs<-1> = Id
End
End Else
* On NT the synonym check is case insensitive
If Upcase(Path) = Upcase(AccPath) Then
SynonymAccs<-1> = Id
End
End
************************
* OS specific code end *
************************
End
Repeat
SynonymAccs = Lower(SynonymAccs)
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
* Check if this directory is the home directory for any users
FileName = "/etc/passwd"
Gosub ReadSeqFile
If Error <> 0 Then
HomeDirFlag = 1 ; * to be on the safe side
End Else
Dc = Dcount(NewText,@Fm)
For I = 1 To Dc
If NewText<I>[1,1] <> "+" Then
If NewText<I>[":",6,1] = AccPath Then
HomeDirFlag = 1
UserList<-1> = NewText<I>[":",1,1]
End
End
Next
End
UserList = Lower(UserList)
End ; * Unix code
************************
* OS specific code end *
************************
OutData<1> = AccPath
OutData<2> = PartFlag
OutData<3> = HomeDirFlag
OutData<4> = SynonymAccs
OutData<5> = UserList
Return
**********************************************************************
* CheckBackupTarget - Validate that a path/device name supplied
* is a valid place to backup to, and return
* a code to indicate what type it is.
*
* Input: Path/device name entered or selected
* by the user
* Output: If the path/device name is not valid
* at all, an error is returned, otherwise
* a code, as follows:
* 1 tape device
* 2 disk file, does not exist yet
* 3 disk file, already exists
**********************************************************************
CheckBackupTarget:
DevName = Params<1>
* Test for a pathname.
If IsFullPath(DevName) Then
FilePath = DevName
End Else
* Input does not appear to be a pathname, so get a path from
* &DEVICE&
Read DevRec From DEVICES, DevName Else
Error = EADM.NOTDEVICE
GoTo Exit.CheckBackupTarget
End
If DevRec<4> Matches TAPE.DEVICE.PATTERN Then
* If it's marked as a tape device, uvbackup will accept it
OutData = 1
GoTo Exit.CheckBackupTarget
End
* For any other device, go on to check the pathname
FilePath = DevRec<6>
End
* Open the file so that we can tell if it's a real file,
* or a char/block special device
OpenSeq FilePath To Temp.File Then
Status Stats From Temp.File Else Stats = ""
CloseSeq Temp.File
* To find out what kind of file this is, examine the MODE value.
* This contains a bitfield (mask 0170000) which holds a value
* for the file type: 2 = char special, 6 = block special
FileMode = OConv(Stats<5>, "MO")
FileMode = FileMode[1, Len(FileMode) - 4]
FileMode = FileMode[2]
If FileMode = 2 Or FileMode = 6 Then
* It's a valid device
OutData = 1
End Else
* It's a disk file that already exists
OutData = 3
End
End Else
* If OpenSeq cannot open it, then either it does not exist
* or it's a directory. We use OpenPath to check that
* it is not a directory.
OutData = 2
OpenPath FilePath To Temp.File Then
Status Stats From Temp.File Else Stats = ""
Close Temp.File
If Stats<21> = 1 Or Stats<21> = 19 Then
* It's a directory
Error = EADM.CANNOTUSEDIR
OutData = ""
End
End Else
call !GET.PATHNAME(FilePath, dir, file,status)
OpenPath dir to Temp.File Else
Error = EADM.NODIRECTORY
OutData = ""
End
End
End ; * OpenSeq
Exit.CheckBackupTarget:
Return
**********************************************************************
* CheckDirectoryPath - Verify that a given path represents an
* existing directory.
*
* Input: pathname
* Output: Nothing - only an error code
**********************************************************************
CheckDirectoryPath:
FilePath = Params<1>
OpenPath FilePath To Temp.File Then
Status Stats From Temp.File Else Stats = ""
Close Temp.File
If Stats<21> = 1 Or Stats<21> = 19 Then
* It's a directory
End Else
* Some other kind of file
Error = EADM.BADDIRECTORY
End
End Else
* Could not open it at all
Error = EADM.NODIRECTORY
End
Return
**********************************************************************
* CheckRestoreSource - Check that a device or pathname given for
* the source of a UVRestore is a usable tape
* or file created by UVBackup.
*
* Input: Device name in &DEVICE&, or pathname
* Output: Output from uvrestore -L
*
**********************************************************************
CheckRestoreSource:
DevName = Params<1>
FilePath = ""
RestoreName = ""
* Test for a pathname.
If IsFullPath(DevName) Then
* If a pathname was supplied, then simply use that
FilePath = DevName
End Else
* Input does not appear to be a pathname, so get a path from
* &DEVICE&
Read DevRec From DEVICES, DevName Else
Error = EADM.NOTDEVICE
GoTo Exit.CheckRestoreSource
End
If DevRec<4> Matches TAPE.DEVICE.PATTERN Then
* If it's marked as a tape device, uvrestore will accept
* the name directly
RestoreName = DevName
End Else
* For any other device, go on to check the pathname
FilePath = DevRec<6>
End
End
If Len(RestoreName) = 0 And Len(FilePath) > 0 Then
* If it's a pathname, check that it exists
OpenSeq FilePath To Temp.File Then
Close Temp.File
RestoreName = FilePath
End Else
Error = EADM.CANTOPEN
GoTo Exit.CheckRestoreSource
End
End
* Should have a name to use with uvrestore by now...
If Len(RestoreName) = 0 Then
Error = EADM.NODEVICE
GoTo Exit.CheckRestoreSource
End
* Device or path name apparently OK - try to read the label
ExLine = OS.EXEC:" '":UV.ROOT:"/bin/uvrestore -L -t ":RestoreName:"'"
GoSub TCLCommand
Del Out<1>
OutData = Out
* Check to see whether uvrestore complained or not
Check.String = UVREADMSG(085400, "")
Loop
While Check.String<1> = "" Do
Del Check.String<1>
Repeat
If OutData<1>[1, Len(Check.String<1>)] = Check.String<1> Then
Error = 0
End Else
Error = EADM.NOTBACKUPTAPE
End
Exit.CheckRestoreSource:
Return
**********************************************************************
* ClearFlag - Clear file inconsistency flag on a recoverable
* file
*
* Input: Pathname
* Output: NONE
**********************************************************************
ClearFlag:
Pathname = Params<1>
ExLine = "RECOVERY.CONSISTENT " : Pathname
Gosub TCLCommand
Out = Trim(Out[1, Len(Out) - 1])
If Out # "" Then
Error = EADM.CLEARFAILED
End
Return
**********************************************************************
* CreateDataSourceEntry - Creates a data source entry
*
* Input: Data Source Name and Details
* Output: None
**********************************************************************
CreateDataSourceEntry:
pos =0
* Add the new entry onto the end of the current details
pos = DCount(DataSourceArray, @FM) +1
DataSourceArray<pos> = Params<1>
DataSourceDetails<pos,2> = Params<2>
DataSourceDetails<pos,3> = Params<3>
DataSourceDetails<pos,4> = Params<4>
DataSourceDetails<pos,5> = Params<5>
* Write the details to the file. The Global Error will be set
* by this function and then sent back by this subroutine, with
* any errors on the write
Error = 0
Gosub WriteDataSources
Return
**********************************************************************
* DeleteDataSourceEntry - Deletes a data source entry
*
* Input: Data Source Name
* Output: None
**********************************************************************
DeleteDataSourceEntry:
ReturnCode = 0
pos =0
DataSource = Params
* Find the data source name in the current list and remove the details
Locate DataSource In DataSourceArray Setting pos Then
Del DataSourceArray<pos>
Del DataSourceDetails<pos>
End Else
ReturnCode = EADM.NOENTRY
End
* Write the details to the file. The Global Error will be set
* by this function and then sent back by this subroutine, with
* any errors on the write
Error = 0
Gosub WriteDataSources
Error = ReturnCode
Return
**********************************************************************
* DBSetup - Runs DBsetup - unix only (for the moment!)
*
* Input: NONE
* Output: NONE
**********************************************************************
DBSetup:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
ExLine = "DBsetup"
GoSub UvCommand
End
************************
* OS specific code end *
************************
Return
***********************************************************************
* DeleteAccount - Deletes an account from UV.ACCOUNT and
* optionally deletes the directory containing
* it.
*
* If this is being used on an NT server,
* transferring the directory is not an
* option.
*
* Input: Key: 1 - leave directory
* 2 - delete directory
* 3 - transfer directory (unix only)
* Account Name
* User Name (only if Key = 3, else null)
* @vm separated list of synonym accounts
* Output: NONE
***********************************************************************
DeleteAccount:
Key = Params<1>
AccName = Params<2>
NewOwner = Params<3>
SynonymAccs = Params<4>
Begin Case
Case Key = 3 ; * Transfer ownership (unix only)
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Params<1> = AccName
Params<2> = NewOwner
Params<3> = "" ; * null group so it won't be changed
GoSub ChownAcc
End
************************
* OS specific code end *
************************
Case Key = 2
* Read pathname from UV.ACCOUNT file. Check that pathname is
* valid by checking if there is a VOC file there. Also check
* that we're not deleting the UVHOME account! If it is ok to
* delete it, delete the directory
PathOk = False
Readv PathName From UVACCOUNT, AccName, 11 Then
OpenSeq PathName:OS.SEP:"VOC" To Temp Then
PathOk = True
CloseSeq Temp
End
* Check that PathName isn't one of the forbidden directories
Find PathName In DONOTDELETE Setting Fmc Then PathOk = False
If PathOk = True Then
If PathName <> UVHOME Then
ExLine = RM.CMD: " -rf ":PathName
GoSub ShellCommand
End
End
End
End Case
Delete UVACCOUNT, AccName
* Now delete synonym accounts if required
If SynonymAccs <> "" Then
SynonymAccs = Raise(SynonymAccs)
NumAccs = DCount(SynonymAccs, @fm)
For I = 1 To NumAccs
Delete UVACCOUNT, SynonymAccs<I>
Next I
End
Return
***********************************************************************
* DeleteDevice - Deletes device record from &DEVICE&. For unix
* systems, if the device is a printer, also
* removes its entry from sp.config.
*
* Input: Device name
* Device type key: 0 - tape
* 1 - printer
* 2 - other
* Output: NONE
***********************************************************************
DeleteDevice:
DevName = Params<1>
Key = Params<2>
Delete DEVICES, DevName
**************************
* OS specific code start *
**************************
* If this is a unix system and the device definition being deleted
* is a printer, remove it from the sp.config file as well
If OS.TYPE = "UNIX" And Key = 1 Then
SpConfigPath = SPOOL.DIR : "/sp.config"
OpenSeq SpConfigPath To FL Then
Temp = ""
Fin = False
Loop
ReadSeq Line From FL Else Fin = True
Until Fin Do
If Not(Line[" ", 1, 1] = DevName) Then
Temp<-1> = Line
End
Repeat
Seek FL, 0 Else Null ; * Go to start of file
Dc = Dcount(Temp, @fm)
For I = 1 To Dc
WriteSeq Temp<I> On FL Else Null
Next
WEOFSeq FL
CloseSeq FL
ExLine = USA.PATH : " -r" ; * Reset spooler
GoSub ShellCommand
End Else
Error = EADM.NOSPCONFIG
End
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* DeleteInfoFile - Deletes a transaction logging information
* file
*
* Input: Key 0 - logging info
* 1 - checkpoint info
* 2 - rollforward info
* Output: NONE
**********************************************************************
DeleteInfoFile:
Key = Params<1>
* Get log directory and add the name of the info file to the path
InfoFile = ""
RECIO(InfoFile, RECIO$PATH)
InfoFile := OS.SEP
Begin Case
Case Key = 0
InfoFile := "uvlogd.info"
Case Key = 1
InfoFile := "uvchkd.info"
Case Key = 2
InfoFile := "uvrolf.info"
Case 1
InfoFile := "uvlogd.info"
End Case
* Doesn't matter if the file exists or not as the outcome is the same
ExLine = RM.CMD : " -f " : InfoFile
Gosub ShellCommand
Return
***********************************************************************
* DeleteUserInfo - Delete the specified user from the UV.LOGINS
* file.
*
* Input: ID of user to be deleted
* Output: None
***********************************************************************
DeleteUserInfo:
Error = 0
Id = Params<1>
OutData = ""
* Open the subscription file
Open '', "UV.LOGINS" To UvLoginsFvar Then
Delete UvLoginsFvar, Id
Close UvLoginsFvar
End Else
Error = EADM.CANTOPEN
End
Return
***********************************************************************
* DeviceList - Get list of tapes, printers or "other" devices.
* Tapes and 'other' devices are taken from the
* &DEVICE& file, printers are taken from &DEVICE&
* and (if on unix) the sp.config file.
*
* Input: Key: 0 - list tapes
* 1 - list printers
* 2 - list other devices
* 3 - list default tapes (DT or DC)
* Output: Dynamic array of device names
***********************************************************************
DeviceList:
Key = Params<1>
* First, run through &DEVICE& building up a list of the devices
* of the type requested
MatchString = "DT":@VM:"DC":@VM:"T":@VM:"C":@VM:"F"
SSelect DEVICES
Done = False
Loop
ReadNext Id Else Done = True
Until Done Do
Readv DevType From DEVICES, Id, 4 Else DevType = ''
Convert " " To @fm In DevType
DevType = DevType<1>
Begin Case
Case DevType = "P"
* This is a printer, if that's what the user requested,
* add it to the list
If Key = 1 Then
OutData<-1> = Id
End
Case DevType ="O"
* This is a not a tape or printer, if the user requested 'other
* devices', add it to the list
If Key = 2 Then
OutData<-1> = Id
End
Case DevType Matches MatchString
* This is a tape device, if that's what the user requested,
* add it to the list
If Key = 0 Then
OutData<-1> = Id
End Else
* Also check for request to list default tapes
If Key = 3 And (DevType = "DC" Or DevType = "DT") Then
OutData<-1> = Id
End
End
End Case
Repeat
**************************
* OS specific code start *
**************************
* If the caller asked for a list of printers and we're on a unix
* system, go through the sp.config file and check that there aren't
* any printers in there that aren't in the &DEVICE& file
If OS.TYPE = "UNIX" And Key = 1 Then
SpConfigPath = SPOOL.DIR : "/sp.config"
OpenSeq SpConfigPath To FL Then
Fin = False
Loop
ReadSeq Line From FL Else Fin = True
Until Fin Do
PName = Line[" ", 1, 1]
Find PName In OutData Setting Fmc Else OutData<-1> = PName
Repeat
CloseSeq FL
End
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* DiagFileData - Runs the File data diags
*
* Input:
* Output: NONE
**********************************************************************
DiagFileData:
Output = ""
Dim CALL.ARGS(10,2)
Dim RES.ARGS(20,2)
If FileFixOpen = 0 Then
Gosub StartFileFixServer
End
If Not(Error) Then
* We are ok, start the call
CALL.ARGS(1,1) = FILEFIX.DIAGDATA ; * Diag Data
CALL.ARGS(1,2) = UVRPC.INT
If RPC.CALL(FileFixConId, " ", 1, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
If RES.ARGS(1,1) Then
Error = RES.ARGS(1,1)
End
OutData = RES.ARGS(2,1)
End Else
Error = STATUS() - 80000
End
End
Return
**********************************************************************
* DiagFileGroups - Runs the file groups diags
*
* Input:
* Output: NONE
**********************************************************************
DiagFileGroups:
Output = ""
Dim CALL.ARGS(10,2)
Dim RES.ARGS(20,2)
If FileFixOpen = 0 Then
Gosub StartFileFixServer
End
If Not(Error) Then
* We are ok, start the call
CALL.ARGS(1,1) = FILEFIX.DIAGGROUPS ; * Diag Groups
CALL.ARGS(1,2) = UVRPC.INT
If RPC.CALL(FileFixConId, " ", 1, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
If RES.ARGS(1,1) Then
Error = RES.ARGS(1,1)
End
OutData = RES.ARGS(2,1)
End Else
Error = STATUS() - 80000
End
End
Return
**********************************************************************
* DiagFileHeader - Runs the file header diags
*
* Input:
* Output: NONE
**********************************************************************
DiagFileHeader:
Output = ""
Dim CALL.ARGS(10,2)
Dim RES.ARGS(20,2)
If FileFixOpen = 0 Then
Gosub StartFileFixServer
End
If Not(Error) Then
Gosub LoadHeaderFileFixFile
If Not(Error) Then
* We are ok, start the call
CALL.ARGS(1,1) = FILEFIX.DIAGHEADER ; * Diag Header
CALL.ARGS(1,2) = UVRPC.INT
If RPC.CALL(FileFixConId, " ", 1, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
If RES.ARGS(1,1) Then
Error = RES.ARGS(1,1)
End
OutData = RES.ARGS(2,1)
End Else
Error = STATUS() - 80000
End
End
End
Return
**********************************************************************
* DiagFileMisc - Runs the file misc diags
*
* Input:
* Output: NONE
**********************************************************************
DiagFileMisc:
Output = ""
Dim CALL.ARGS(10,2)
Dim RES.ARGS(20,2)
If FileFixOpen = 0 Then
Gosub StartFileFixServer
End
If Not(Error) Then
* We are ok, start the call
CALL.ARGS(1,1) = FILEFIX.DIAGMISC ; * Diag Misc
CALL.ARGS(1,2) = UVRPC.INT
If RPC.CALL(FileFixConId, " ", 1, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
If RES.ARGS(1,1) Then
Error = RES.ARGS(1,1)
End
OutData = RES.ARGS(2,1)
End Else
Error = STATUS() - 80000
End
End
Return
**********************************************************************
* DiagPhysicalStructure - Runs the
*
* Input:
* Output: NONE
**********************************************************************
DiagPhysicalStructure:
Output = ""
Dim CALL.ARGS(10,2)
Dim RES.ARGS(20,2)
If FileFixOpen = 0 Then
Gosub StartFileFixServer
End
If Not(Error) Then
* We are ok, start the call
CALL.ARGS(1,1) = FILEFIX.DIAGPHYSICALSTRUCT ; * Diag Phys Struct
CALL.ARGS(1,2) = UVRPC.INT
If RPC.CALL(FileFixConId, " ", 1, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
If RES.ARGS(1,1) Then
Error = RES.ARGS(1,1)
End
OutData = RES.ARGS(2,1)
End Else
Error = STATUS() - 80000
End
End
Return
**********************************************************************
* EnablePrinting - Enables or disables printing on a printer
* Unix only
*
* Input: Action: 0 - disallow printing
* 1 - allow printing
* Printername
* Output: NONE
**********************************************************************
EnablePrinting:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
GoSub CheckSpooler
If Error # 0 Then
Return
End
Key = Params<1>
PrinterName = Params<2>
If Key = 0 Then
ExLine = USA.PATH : " -o -p " : PrinterName
End Else
ExLine = USA.PATH : " +o -p " : PrinterName
End
GoSub ShellCommand
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* EnumPrinters - Returns a list of the printers defined in
* the print manager on the server machine.
* NT only.
*
* Input: NONE
* Output: Dynamic array of printers
**********************************************************************
EnumPrinters:
**************************
* OS specific code start *
**************************
If OS.TYPE # "UNIX" Then
DECLARE GCI AdmListPrinters
NumPrinters = 0
NumPrinters = AdmListPrinters(Printers)
If NumPrinters > 0 Then
OutData = Printers
End
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* ExamineDeadLockLog - Returns the Lock Log to examine
*
* Input: Log Path
* Output: Log data
**********************************************************************
ExamineDeadLockLog:
ReturnCode = 0
NewText = ""
Line = ""
LogFile = Trim(Params):OS.SEP:"uvdlockd.log"
OpenSeq LogFile To LogFvar Locked
ReturnCode = EADM.RECLOCKED
End
Then
* In case the file is huge, seek to the end and go back 16k
* bytes. Ignore the outcome of this - if it fails, it means
* the file isn't that long, so just read the whole file.
* NB. Can't return more data than this at the moment due to
* RPC package size limitations
Seek LogFvar, -16384, 2 Then
End
Done = False
Loop
ReadSeq Line From LogFvar Else Done = True
Until Done or Status() Do
NewText<-1> = Line
Repeat
CloseSeq LogFvar
OutData = Change(NewText, @FM, CRLF)
End
Else
ReturnCode = EADM.NOFILE
End
Error = ReturnCode
Return
**********************************************************************
* FixTheFile - Runs the File data fixing
*
* Input:
* Output: NONE
**********************************************************************
FixTheFile:
Output = ""
Dim CALL.ARGS(10,2)
Dim RES.ARGS(20,2)
FixFilename = Params<1>
FixFilePath = Params<2>
If FileFixOpen = 0 Then
Gosub StartFileFixServer
End
If Not(Error) Then
* We are ok, start the call
CALL.ARGS(1,1) = FILEFIX.FIXFILE ; * Fix the file
CALL.ARGS(1,2) = UVRPC.INT
CALL.ARGS(2,1) = FixFilename
CALL.ARGS(2,2) = UVRPC.STRING
CALL.ARGS(3,1) = FixFilePath
CALL.ARGS(3,2) = UVRPC.STRING
If RPC.CALL(FileFixConId, " ", 3, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
OutData = RES.ARGS(2,1)
End Else
Error = STATUS() - 80000
End
End
Return
**********************************************************************
* GetAccountFiles - Returns a list of files local to an account
*
* Input: Account name or pathname
* Output: Sorted list of file names, separated
* by field marks.
**********************************************************************
GetAccountFiles:
AccountName = Params<1>
If IsFullPath(AccountName) Then
AccountPath = AccountName
End Else
* Specific account name
ReadV AccountPath From UVACCOUNT, AccountName, 11 Else
Error = EADM.CANTREADPATH
Return
End
End
* We need a temporary file pointer to be able to do SSELECT
TempRec = "F" : @FM : AccountPath : OS.SEP : "VOC" : @FM : "D_VOC"
Write TempRec On VOC, "BROWSEPTR"
ExLine = \SSELECT BROWSEPTR WITH F1 LIKE "'F'..."\
ExLine := " AND F2 UNLIKE ...":OS.SEP:"..."
**************************
* OS specific code start *
**************************
* Checking for / on NT as this is still a valid separator in UniVerse files.
If OS.TYPE # "UNIX" Then
ExLine := " AND F2 UNLIKE .../..."
End
************************
* OS specific code end *
************************
Gosub TCLCommand
Done = False
Loop
ReadNext Id From SList Else Done = True
Until Done Do
OutData<-1> = Id
Repeat
Return
**********************************************************************
* GetAccountPath - Returns the pathname of an account
*
* Input: Account name or pathname
* Output: Account path, or empty if the path
* is not a valid account.
**********************************************************************
GetAccountPath:
AccountName = Params<1>
If IsFullPath(AccountName) Then
AccountPath = AccountName
End Else
* Specific account name
ReadV AccountPath From UVACCOUNT, AccountName, 11 Else
Error = EADM.CANTREADPATH
Return
End
End
* Open the VOC file for the specified account
OpenPath AccountPath : OS.SEP : "VOC" To Remote.Voc Then
Close Remote.Voc
OutData = AccountPath
End Else
Error = EADM.BADACCOUNT
End
Return
**********************************************************************
* GetDataSources - Returns the data sources
*
* Input: None
* Output: Data sources in the config file
**********************************************************************
GetDataSources:
ReturnCode = 0
pos =0
datasourcecount = 0
lp = 1
line=""
Templine = ""
DataSourceDetails = ""
DataSourceArray = ""
PreDataSources = ""
PostDataSources = ""
eof = 0
config.file = UVHOME : OS.SEP : "uvodbc.config"
OpenSeq config.file To FConfig.file Then
* Find the ODBC START SOURCES marker, anything before this are not adat sources
Loop
ReadSeq line From FConfig.file Then
Templine=Trim(line)
If Templine = "[ODBC DATA SOURCES]" Then
eof = 1
End
PreDataSources<lp> = line
lp +=1
End Else
eof = 1
End
Until eof Do
Repeat
* Load the data sources into the control arrays. If we run out of data
* sources before the end of the file set eod (end of data) otherwise
* set eof. This is used by the post data source handler to defermine
* whether to load the last line read into the post data array.
eof = 0
eod = 0
Loop
ReadSeq line From FConfig.file Then
line=Trim(line)
If line[1,1] = "[" Then
eod = 1
End
End Else
eof = 1
End
Until eof or eod Do
If line[1,1] = "<" Then
datasourcecount +=1
DataSourceArray<datasourcecount,1> = Field(line[2,999],">",1)
End
Begin Case
Case line[1,8] = "DBMSTYPE"
DataSourceDetails<datasourcecount,2> = Trim(Field(line,"=",2))
Case line[1,7] = "network"
DataSourceDetails<datasourcecount,3> = Trim(Field(line,"=",2))
Case line[1,7] = "service"
DataSourceDetails<datasourcecount,4> = Trim(Field(line,"=",2))
Case line[1,4] = "host"
DataSourceDetails<datasourcecount,5> = Trim(Field(line,"=",2))
End Case
Repeat
* If eod (end of data) load the last line read into the post data array
If eod Then
PostDataSources<1> = line
lp = 2
End Else
lp = 1
End
eof = 0
Loop
ReadSeq line From FConfig.file Then
PostDataSources<lp> = line
lp +=1
End Else
eof = 1
End
Until eof Do
Repeat
CloseSeq FConfig.file
End
OutData = DataSourceArray
Error = ReturnCode
Return
**********************************************************************
* GetDataSourceEntry - Returns a data source entry
*
* Input: Data Source Name
* Output: Data source details
**********************************************************************
GetDataSourceEntry:
ReturnCode = 0
pos =0
DataSource = Params
OutData = ""
* Find the specified entry and return the details for it.
Locate DataSource In DataSourceArray Setting pos Then
OutData<1> = DataSourceDetails<pos,2>
OutData<2> = DataSourceDetails<pos,3>
OutData<3> = DataSourceDetails<pos,4>
OutData<4> = DataSourceDetails<pos,5>
End Else
ReturnCode = EADM.NOENTRY
End
Error = ReturnCode
Return
**********************************************************************
* GetDeadLockConfig - Returns the dead locking config information
*
* Input: None
* Output: DeadLock config information.
**********************************************************************
GetDeadLockConfig:
ReturnCode = 0
line=''
pos =0
eof = 0
OutData = ""
* Open the uvdlockd config file in the UniVerse home account
config.file = UVHOME : OS.SEP : "uvdlockd.config"
OpenSeq config.file To FConfig.file Then
* Parse out the deadlock configuration details.
loop
ReadSeq line From FConfig.file Else eof = 1
until eof do
line=Trim(line)
Begin Case
Case line[1,3]='tim'
pos = INDEX(line, "=",1)
If pos THEN
OutData<1> = line[pos+1,99]
End
Case line[1,3]='sta'
pos = INDEX(line, "=",1)
If pos THEN
OutData<2> = line[pos+1,99]
End
Case line[1,3]='res'
pos = INDEX(line, "=",1)
If pos THEN
OutData<3> = line[pos+1,99]
End
Case line[1,3]='log'
pos = INDEX(line, "=",1)
If pos THEN
LogFilePath = line[pos+1,99]
If LogFilePath = "" THEN
LogFilePath = UV.ROOT
End
OutData<4> = LogFilePath
End
End Case
Repeat
CloseSeq FConfig.file
End
Else
ReturnCode = EADM.NOFILE
End
Error = ReturnCode
Return
**********************************************************************
* GetDeadLockState - Returns the state of the dead lock process
*
* Input: None
* Output: 0 for down or 1 for up.
**********************************************************************
GetDeadLockState:
LogState = 0
OutData = ""
* Get Log State
RECIO(LogState, DLINFO$AI.STATE, RECIO$DLINFO)
OutData = LogState
Error = @SYSTEM.RETURN.CODE
Return
**********************************************************************
* GetDevice - Returns a device record. For tapes and
* 'other' devices, this comes from the &DEVICE&
* file. For printers, on a unix system, the
* device definition held in sp.config takes
* precedence over the one held in the &DEVICE&
* file. For non-unix, or if there isn't a
* definition for the requested printer in the
* sp.config file, it is read from the &DEVICE&
* file.
*
* Input: Device name
* Device type key: 0 - tape
* 1 - printer
* 2 - other
* Output: Device record
**********************************************************************
GetDevice:
DevName = Params<1>
Key = Params<2>
DevRec = ""
**************************
* OS specific code start *
**************************
* If this is a unix system, and a printer device definition has
* been requested, look for it in the sp.config file first. Even
* if we get a definition from the sp.config file, we still have
* to get the description from the &DEVICE& record
If OS.TYPE = "UNIX" And Key = 1 Then
Gosub GetPrinter
If DevRec <> "" Then ; * printer found in sp.config
Readv Descr From DEVICES, DevName, 1 Then
DevRec<1> = Descr
End
End
End
************************
* OS specific code end *
************************
* If we haven't already read the record (ie. its not a printer or
* we're not on a unix system or we are on a unix system but the
* printer wasn't defined in sp.config), read from the &DEVICE& file
If DevRec = "" Then
Read DevRec From DEVICES, DevName Else
Error = EADM.NOTDEVICE
End
End
If Error = 0 Then
OutData = DevRec
End
Return
**********************************************************************
* GetDrives - Returns a list of available drives for use
* with Browse (NT only)
*
* Input: NONE
* Output: List of drives
**********************************************************************
GetDrives:
DECLARE GCI AdmListDrives
num.drives = AdmListDrives(OutData)
Return
**********************************************************************
* GetFileDetails - Returns all the file details on a file
*
* Input: Filename
* Output: All file details
**********************************************************************
GetFileDetails:
Output = ""
Dim CALL.ARGS(10,2)
Dim RES.ARGS(20,2)
FixFilename = Params<1>
FixFilePath = Params<2>
If FileFixOpen = 0 Then
Gosub StartFileFixServer
End
If Not(Error) Then
* We are ok, start the call
* First Open the File
Gosub OpenFileFixFile
If Not(Error) Then
Gosub LoadHeaderFileFixFile
If Not(Error) Then
CALL.ARGS(1,1) = FILEFIX.GETFILEINFO ; * Get File Info
CALL.ARGS(1,2) = UVRPC.INT
If RPC.CALL(FileFixConId, " ", 1, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
OutData = RES.ARGS(2,1)
End Else
Error = STATUS() - 80000
End
* Unload the File Header
Gosub UnloadHeaderFileFixFile
End
* Close The file
Gosub CloseFileFixFile
End Else
* Test for the error for type 1 or type 19
If Error = FILEFIX.TYPE1FILE Then
OutData = STR(@AM,3):"1"
Error = 0
End Else
If Error = FILEFIX.TYPE19FILE Then
OutData = STR(@AM,3):"19"
Error = 0
End
End
End
End
Return
**********************************************************************
* GetFixErrors - Returns all the file errors after a run
*
* Input:
* Output: All file Errors
**********************************************************************
GetFixErrors:
Output = ""
ErrorList = ""
Dim CALL.ARGS(10,2)
Dim RES.ARGS(20,2)
If FileFixOpen = 0 Then
Gosub StartFileFixServer
End
If Not(Error) Then
* We are ok, start the call
CALL.ARGS(1,1) = FILEFIX.GETERRORS ; * Get Errors
CALL.ARGS(1,2) = UVRPC.INT
If RPC.CALL(FileFixConId, " ", 1, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
OutData = RES.ARGS(2,1)
ErrorList = RES.ARGS(3,1)
Convert @VM To @SM In ErrorList
Convert @FM To @VM In ErrorList
OutData:= @FM: ErrorList
End Else
Error = STATUS() - 80000
End
End
Return
**********************************************************************
* GetFilePath - Returns the OS pathname of a given uniVerse
* file, having validated that it exists and
* can be opened.
*
* Input: Account Name or Pathname
* File Name
* Output: Absolute pathname of file
**********************************************************************
GetFilePath:
PathOnly = 0
Count = 0
AccountName = Params<1,1>
FileName = Params<2>
PathOnly = Params<1,2>
* Check if the input is an account or path name.
If IsFullPath(AccountName) Then
AccountPath = AccountName
End Else
* If it's not a path name, read the path from UV.ACCOUNT
ReadV AccountPath From UVACCOUNT, AccountName, 11 Else
Error = EADM.CANTREADPATH
GoTo Exit.GetFilePath
End
End
* Open the VOC file for the specified account
OpenPath AccountPath : OS.SEP : "VOC" To Remote.Voc Else
Error = EADM.BADACCOUNT
GoTo Exit.GetFilePath
End
* Check the VOC entry for the specified file
* Do we have a dict?
If Index(FileName, "DICT", 1) Then
FileDict = Field(FileName," ",1)
FileData = field(FileName," ",2)
End Else
FileDict = ""
FileData = FileName
End
* Read from VOC. If item doesn't exist, assume that the name
* given is an OS name relative to the account
Read FileItem From Remote.Voc, FileData Then
If UpCase(FileItem[1,1]) # "F" Then
Error = EADM.BADVOCITEM
GoTo Exit.GetFilePath
End
If Len(FileDict) > 0 Then
FilePath = FileItem<3>
If Len(FilePath) = 0 Then
Error = EADM.BADDICTPATH
GoTo Exit.GetFilePath
End
End Else
FilePath = FileItem<2>
If Len(FilePath) = 0 Then
Error = EADM.BADDATAPATH
GoTo Exit.GetFilePath
End
End
End Else
* No VOC record
FilePath = FileName
End
* Check that the file itself can be opened
If IsFullPath(FilePath) Then
OutData = FilePath
End Else
OutData = AccountPath : OS.SEP : FilePath
End
OpenPath OutData To Temp.File Then
Close Temp.File
End Else
OpenSeq OutData To Temp.File Then
CloseSeq Temp.File
End Else
* Could not open the file either way
Error = EADM.BADFILE
End
End
If PathOnly Then
Convert "\" To @FM In OutData
Convert "/" To @FM In OutData
Count = DCount(OutData, @FM)
If Count GT 1 Then
Temp = OutData<Count>
Del OutData<Count>
End
Convert @FM To OS.SEP In OutData
OutData=OutData: @VM: Temp
End
Exit.GetFilePath:
Close Remote.Voc
Return
**********************************************************************
* GetFilesWithDetails - Returns all the files and there details
* from an account
*
* Input: Account
* Output: List offiles and their details
**********************************************************************
GetFilesWithDetails:
OutData = ""
AccountName = Params<1>
DataDict = Params<2>
If IsFullPath(AccountName) Then
AccountPath = AccountName
End Else
* Specific account name
ReadV AccountPath From UVACCOUNT, AccountName, 11 Else
Error = EADM.CANTREADPATH
Return
End
End
* Open the VOC file for the specified account
OpenPath AccountPath : OS.SEP : "VOC" To Remote.Voc Else
Error = EADM.BADACCOUNT
Goto Exit.GetFilesWithDetails
End
Close Remote.Voc
* We need a temporary file pointer to be able to do SSELECT
TempRec = "F" : @FM : AccountPath : OS.SEP : "VOC" : @FM : "D_VOC"
Write TempRec On VOC, "BROWSEPTR"
ExLine = \SSELECT BROWSEPTR WITH F1 LIKE "'F'..." AND WITH F4 UNLIKE "M..."\
ExLine := " AND F2 UNLIKE ...":OS.SEP:"... AND WITH @ID NE '&UFD&'"
**************************
* OS specific code start *
**************************
* Checking for / on NT as this is still a valid separator in UniVerse files.
If OS.TYPE # "UNIX" Then
ExLine := " AND F2 UNLIKE .../..."
End
************************
* OS specific code end *
************************
Open "BROWSEPTR" To F$Remote Then
Gosub TCLCommand
Done = False
Loop
ReadNext Id From SList Else Done = True
While Id Do
Read A$Rec From F$Remote, Id Then
If DataDict Then
FilePath = A$Rec<3>
End Else
FilePath = A$Rec<2>
End
FilePath=AccountPath:OS.SEP:FilePath
OpenPath FilePath To F$RemoteFile Then
If DataDict Then
Convert "\":"/" To @FM:@FM In FilePath
Id = FilePath<DCount(FilePath, @FM), 1>
End
OutData<-1> = Id: @VM : STATUS() : @VM : INMAT()
Close F$RemoteFile
End Else
End
End Else
End
Repeat
End
Exit.GetFilesWithDetails:
Return
**********************************************************************
* GetLocalAccountPaths - Returns a list, space-separated, of the
* pathnames of all the local accounts on the
* system, without duplicates. This
* information is used when asked to back up
* all accounts on the system.
*
* Input: None
* Output: List of pathnames, separated by
* spaces
**********************************************************************
GetLocalAccountPaths:
* This code is taken from UVBACKUP.B
* To exclude remote accounts, we need to do a separate
* step, since UNIQUE hates having selection criteria
Execute \SELECT UV.ACCOUNT WITH UNIQUE.PATH UNLIKE "...'!'..." \ Rtnlist Gpaths Capturing Screen
Execute "SELECT UV.ACCOUNT SAVING UNIQUE UNIQUE.PATH" Passlist Gpaths Capturing Screen
* convert to dynamic array
ReadList OutData Then
Convert @FM To " " In OutData
End Else
Error = EADM.CANTREADPATHLIST
End
Return
**********************************************************************
* GetLoggingState - Returns the current status of transaction
* logging
*
* Input: NONE
* Output: Logging state
* Archive flag
* Archive type
* Checkpoint flag
* Logging directory
* Device list (if archiving to tape)
* Device name
* Device state
**********************************************************************
GetLoggingState:
DevInfo = ""
* First get the logging state
LogState = ""
RECIO(LogState, FINFO$AI.STATE, RECIO$FINFO)
* Is archiving switched on
Temp = 0
RECIO(Temp, FINFO$AI.ARCHIVE, RECIO$FINFO)
If Temp = 0 Then
ArchiveFlag = 0
End Else
ArchiveFlag = 1
End
* Now find out what we are archiving to: disk or tape
Temp = 0
DevList = ""
RECIO(Temp, FINFO$AI.ARCHIVE.TAPE, RECIO$FINFO)
If Temp = 0 Then
ArchiveType = 0 ; * archiving to disk
End Else
ArchiveType = 1 ; * archiving to tape
RECIO(DevList, "", RECIO$DEVICELIST)
* For each logging device, get its state from its &DEVICE& record
DevList = Raise(DevList)
NumDevs = DCount(DevList, @fm)
For Index = 1 To NumDevs
Readv State From DEVICES, DevList<Index>, 18 Then
State = Trim(State)
Begin Case
Case State = "LG_INUSE"
State = "In Use"
Case State = "LG_FULL"
State = "Full"
Case State = ""
State = ""
Case 1
State = "Unknown"
End Case
End Else
State = "Unknown"
End
DevInfo<-1> = DevList<Index> : @vm : State
Next Index
End
* Checkpoint flag
Temp = 0
RECIO(Temp, FINFO$AI.CHECKPOINT, RECIO$FINFO)
If Temp = 0 Then
CheckPointFlag = 0
End Else
CheckPointFlag = 1
End
* Get logging directory
LogDir = ""
RECIO(LogDir, RECIO$PATH)
LogRaw = ""
RECIO(LogRaw, RECIO$RAWPATH )
OutData = LogState
OutData<-1> = ArchiveFlag
OutData<-1> = ArchiveType
OutData<-1> = CheckPointFlag
OutData<-1> = LogDir
OutData<-1> = Lower(DevInfo)
OutData<-1> = @fm:LogRaw
Return
**********************************************************************
* GetMachineType - Temporary fix until this can be got from
* session properties
*
* Input: NONE
* Output: Machine type: 0 = NT, 1 - unix
**********************************************************************
GetMachineType:
If OS.TYPE = "UNIX" Then
OutData = "1"
end else
OutData = "0"
End
Return
**********************************************************************
* GetMaxBlockSize - Returns the maximum tape block size in bytes
* NOTE: this will be ignored by the client if
* this is an NT system
*
* Input: NONE
* Output: Max block size
**********************************************************************
GetMaxBlockSize:
* Sytem 63 returns the value of BLKMAX from the uvconfig
* parameters.
OutData = System(63)
Return
**********************************************************************
* GetMultiLevelFiles - Returns all the multi level files in an account
*
* Input: Account
* Output: List of multi level files
**********************************************************************
GetMultiLevelFiles:
OutData = ""
AccountName = Params<1>
If IsFullPath(AccountName) Then
AccountPath = AccountName
End Else
* Specific account name
ReadV AccountPath From UVACCOUNT, AccountName, 11 Else
Error = EADM.CANTREADPATH
Return
End
End
* We need a temporary file pointer to be able to do SSELECT
TempRec = "F" : @FM : AccountPath : OS.SEP : "VOC" : @FM : "D_VOC"
Write TempRec On VOC, "BROWSEPTR"
ExLine = \SSELECT BROWSEPTR WITH F1 LIKE "'F'..." AND WITH F4 LIKE "M..."\
ExLine := " AND F2 UNLIKE ...":OS.SEP:"..."
**************************
* OS specific code start *
**************************
* Checking for / on NT as this is still a valid separator in UniVerse files.
If OS.TYPE # "UNIX" Then
ExLine := " AND F2 UNLIKE .../..."
End
************************
* OS specific code end *
************************
Open "BROWSEPTR" To F$Remote Then
Gosub TCLCommand
Done = False
Loop
ReadNext Id From SList Else Done = True
While Id Do
OutData<-1> = Id
Repeat
Close F$Remote
End
Return
**********************************************************************
* GetMultiLevelFilesWithDetails - Returns all the multi level files
* in an account with their details
*
* Input: Account
* Output: List of multi level files and their
* details
**********************************************************************
GetMultiLevelFilesWithDetails:
OutData = ""
Finish = 0
Ct = 0
AccountName = Params<1>
MultiLevelFile = Params<2>
DataDict = Params<3>
If IsFullPath(AccountName) Then
AccountPath = AccountName
End Else
* Specific account name
ReadV AccountPath From UVACCOUNT, AccountName, 11 Else
Error = EADM.CANTREADPATH
Return
End
End
* We need a temporary file pointer to be able to do SSELECT
TempRec = "F" : @FM : AccountPath : OS.SEP : "VOC" : @FM : "D_VOC"
Write TempRec On VOC, "BROWSEPTR"
Open "BROWSEPTR" To F$Remote Then
Read MLRec From F$Remote, MultiLevelFile Then
Ok = True
If Not(DataDict) Then
Finish = DCount(MLRec<7>, @VM)
For Ct = 1 To Finish
Id = MLRec<7,Ct>
FilePath = MLRec<2>
FilePath=AccountPath:OS.SEP:FilePath:OS.SEP:Id
OpenPath FilePath To F$RemoteFile Then
OutData<-1> = Id: @VM : STATUS() : @VM : INMAT()
Close F$RemoteFile
End Else
End
Next Ct
End Else
FilePath = MLRec<3>
FilePath=AccountPath:OS.SEP:FilePath
OpenPath FilePath To F$RemoteFile Then
Convert "\":"/" To @FM:@FM In FilePath
Id = FilePath<DCount(FilePath, @FM), 1>
OutData<-1> = Id: @VM : STATUS() : @VM : INMAT()
Close F$RemoteFile
End Else
End
End
End Else
Error = EADM.CANTREAD
End
Close F$Remote
End
Return
**********************************************************************
* GetNLSMaps - Returns a list of the installed NLS maps. If
* NLS is not in use, this will be an empty list.
*
* Input: NONE
* Output: Dynamic array of NLS map names
**********************************************************************
GetNLSMaps:
* First check if *NLS.LISTMAPS is cataloged - if it isn't, then
* NLS is not in use and we can't get the maps. If it is cataloged,
* call it to get the maps. If we can't get the maps, just return
* nothing - the client will handle it
MapData = ""
Call !EXIST("*NLS.LISTMAPS", Code)
If Code Then
Call *NLS.LISTMAPS(MapData, 'AL', Code)
If Code = 0 Then
Dc = Dcount(MapData, @fm)
For I = 1 To Dc
OutData<-1> = MapData<I,1>
Next I
End
End
Return
**********************************************************************
* GetPrinterGroups - Returns printer group information
* Unix only
*
* Input: NONE
* Output: Array of printer group information:
* printer group name
* user name
* user name
* .....
* printer name
* printer name
* .....
**********************************************************************
GetPrinterGroups:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
PGroupFile = SPOOL.DIR:"/print_group"
OpenSeq PGroupFile To PGroupFvar Then
Status FileStats From PGroupFvar Then
PGroupPerms = Oconv(FileStats<5>, "MO")[4,3]
End Else
PGroupPerms = 0
End
Done = False
Loop
ReadSeq Line From PGroupFvar Else Done = True
Until Done Or Status()
Convert ":":"," To @VM:@SM In Line
OutData<-1> = Line
Repeat
CloseSeq PGroupFvar
End Else
OutData = "" ; * File doesn't exist - no pgroups
End
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* GetRPCInfo - Returns RPC port number and list of hosts
* for unix only
*
* Input: NONE
* Output: RPC port number
* List of node name & address
**********************************************************************
GetRPCInfo:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
* Open /etc and keep it open to retain locks. It will be closed
* when the user exits from network services
OpenPath "/etc" To ETC.FVAR Else
Error = EADM.CANTOPEN
End
* First get RPC port number. There has to be one, or the system
* administration tool can't be running as it uses the uvrpc!
If Error = 0 Then
Readu Services From ETC.FVAR, "services" Locked
Error = EADM.RECLOCKED
End Else
Error = EADM.CANTREAD
End
End
If Error = 0 Then
Convert Char(10) To @fm In Services
FindStr "uvrpc" In Services Setting LineNo Then
PortLine = Services<LineNo>
PortLineLen = Len(PortLine)
Pos = 1
Loop
Until PortLine[Pos,1] = " " Or PortLine[Pos,1] = Char(9) Or Pos > PortLineLen
Pos += 1
Repeat
Loop
While (PortLine[Pos,1] = " " Or PortLine[Pos,1] = Char(9)) And Pos < PortLineLen
Pos += 1
Repeat
NumLen = Index(PortLine[Pos, PortLineLen - Pos], '/', 1) - 1
OutData = PortLine[Pos, NumLen]
End Else
* cater for there not being a port number, even though this is
* very unlikely
OutData<1> = ""
End
Gosub ReadAndConvertHosts
If Error = 0 Then
* Now go through the converted host data and set up an
* IPAddress/MachineName pair for each Machine name, whether
* it is a synonym or not
For Index = 1 To Dcount(HostData,@fm)
For Index2 = 1 To Dcount(HostData<Index, 2>, @sm)
If HostData<Index, 2, Index2> # "" Then
OutData<-1> = HostData<Index, 2, Index2> : @vm : HostData<Index, 1>
End
Next Index2
Next Index
End
End
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* GetSpoolConfig - Returns spooler configuration data
* Unix only
*
* Input: NONE
* Output: Spool directory
* Error log path
* Activity log path
* Logging enabled flag
* Chronological order flag
* Timer value
**********************************************************************
GetSpoolConfig:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
DefaultInput = ""
* Open the UVRC file - this locks it so the parameters cannot be
* changed by anyone else. It is closed, either by the SetSpoolConfig
* command, or the CloseUVRC command. UVRC and UVRC.OPEN are both
* held in common
OpenSeq UVRCFILE To UVRC Locked
Error = EADM.UVRCLOCKED
UVRC.OPEN = False
Return
End Else
Error = EADM.CANTOPENUVRC
UVRC.OPEN = False
Return
End
UVRC.OPEN = True
* Get parameter information. USD.SCRIPT is held in common. Use
* this opportunity to check that SPOOL.DIR hasn't changed since
* we initialised
Call *SP.GET.UVRC.B(DefaultInput, USD.SCRIPT)
If DefaultInput<1> <> SPOOL.DIR Then
SPOOL.DIR = DefaultInput<1>
End
OutData<1> = DefaultInput<1> ; * Spool dir
OutData<2> = DefaultInput<2> ; * Error log
OutData<3> = DefaultInput<3> ; * Activity log
Temp = Convert(" ",@FM,Trim(USD.SCRIPT<4>))
Locate "-L" In Temp Setting Loc Then
OutData<4> = "1" ; * Logging enabled
End Else
OutData<4> = "0" ; * Logging disabled
End
Locate "-t" In Temp Setting Loc Then
OutData<5> = "1" ; * Chronlogical order
End Else
OutData<5> = "0" ; * Not chronological
End
Locate "-w" In Temp Setting Loc Then
OutData<6> = Temp<Loc+1> ; * Timer value
End Else
OutData<6> = "10" ; * Default timer value
End
End
************************
* OS specific code end *
************************
Return
************************************************************************
* GetTelnetInfo - Returns telnet data for NT only
*
* Input: NONE
* Output: Telnet port number
* User policy (0 - attach to home account
* 1 - attach to home directory
* 2 - attach to any account
* 3 - attach to any directory)
* Max. logon attempts
* Logon pause (seconds)
* Logon timeout (seconds)
* Termination pause (seconds)
************************************************************************
GetTelnetInfo:
**************************
* OS specific code start *
**************************
If OS.TYPE <> "UNIX" Then
DECLARE GCI UVREGgetint
* First, get the telnet port number out of the services file
ExLine = "echo %SystemRoot%"
Gosub ShellCommand
Root = Out<1>
EtcPath = Root : "\SYSTEM32\DRIVERS\ETC"
* Open etc file and keep it open to retain locks. It will be closed
* when the user exits from network services
OpenPath EtcPath To ETC.FVAR Else
Error = EADM.CANTOPEN
End
* First look for the 'uvtelnet' entry. If there isn't one, then
* look for the 'telnet' entry. If there isn't one of those
* either, use the default value
If Error = 0 Then
Readu Services From ETC.FVAR, "services" Locked
Error = EADM.RECLOCKED
End Else
Error = EADM.CANTREAD
End
End
Found = False
If Error = 0 Then
Convert Char(10) To @fm In Services
FindStr "uvtelnet" In Services Setting LineNo Then
Found = True
End
If Found = False Then
FindStr "telnet" In Services Setting LineNo Then
Found = True
End
End
If Found Then
PortLine = Services<LineNo>
PortLineLen = Len(PortLine)
Pos = 1
Loop
Until PortLine[Pos,1] = " " Or PortLine[Pos,1] = Char(9) Or Pos > PortLineLen
Pos += 1
Repeat
Loop
While (PortLine[Pos,1] = " " Or PortLine[Pos,1] = Char(9)) And Pos < PortLineLen
Pos += 1
Repeat
NumLen = Index(PortLine[Pos, PortLineLen - Pos], '/', 1) - 1
PortNo = PortLine[Pos, NumLen]
End Else
* No 'uvtelnet' or 'telnet' entry, use default value
PortNo = DFLT.TELNETPORT
End
End
* Now use GCI routine to read the other values from the
* registry - again, if any of them aren't present, use the
* default value
If Error = 0 Then
Result = UVREGgetint("UserPolicy", UserPolicy)
If Result # 0 Then
If Result = WINERR.NOREGENTRY Then ; * use default
UserPolicy = DFLT.USERPOLICY
End Else
Error = EADM.CANTREAD
End
End
End
If Error = 0 Then
Result = UVREGgetint("MaxLogonAttempts", MaxLogon)
If Result # 0 Then
If Result = WINERR.NOREGENTRY Then ; * use default
MaxLogon = DFLT.MAXLOGON
End Else
Error = EADM.CANTREAD
End
End
End
If Error = 0 Then
Result = UVREGgetint("LogonPause", LogonPause)
If Result # 0 Then
If Result = WINERR.NOREGENTRY Then ; * use default
LogonPause = DFLT.LOGONPAUSE
End Else
Error = EADM.CANTREAD
End
End
End
If Error = 0 Then
Result = UVREGgetint("LogonTimeout", LogonTimeout)
If Result # 0 Then
If Result = WINERR.NOREGENTRY Then ; * use default
LogonTimeout = DFLT.LOGONTIMEOUT
End Else
Error = EADM.CANTREAD
End
End
End
If Error = 0 Then
Result = UVREGgetint("TerminationPause", TermPause)
If Result # 0 Then
If Result = WINERR.NOREGENTRY Then ; * use default
TermPause = DFLT.TERMPAUSE
End Else
Error = EADM.CANTREAD
End
End
End
If Error = 0 Then
OutData = PortNo : @fm : UserPolicy : @fm : MaxLogon : @fm
OutData := LogonPause : @fm : LogonTimeout : @fm :TermPause
End
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* GetTransferLogs - Finds out which logs are ready for transfer,
* checks that they are sequential and returns
* the lowest and highest log file numbers
* If there are no logs ready for transfer, no
* data is returned.
*
* Input: NONE
* Output: First log
* Last log
* Log path
**********************************************************************
GetTransferLogs:
* Get list of logs which are ready for transfer
Execute "SSELECT UV_LOGS WITH STATUS = Full BY @ID TO 0" Capturing Out
ReadList IdArray Then
IdNum = DCount(IdArray, @fm)
FirstLog = IdArray<1>
LastLog = IdArray<IdNum>
For I = 1 To IdNum
If IdArray<I> # (FirstLog - 1 + I) Then
Error = EADM.BADLOGORDER
Return
End
Next I
Path = ""
RECIO(Path, RECIO$PATH)
OutData<1> = FirstLog
OutData<2> = LastLog
OutData<3> = Path
End
Return
************************************************************************
* GetUserInfo:
*
*
* Input: NONE
* Output: An array with the user login account
* information in it.
**********************************************************************
GetUserInfo:
Error = 0
Id = ""
OutData = ""
Line = ""
Rec = ""
* Open the subscription file
Open '', "UV.LOGINS" To UvLoginsFvar Then
SSelect UvLoginsFvar
Fin = False
Loop
Readnext Id Then
Read Rec From UvLoginsFvar, Id Then
Desc = Rec<5>
* Build the return line
Line = Id : @vm : Desc
OutData<-1> = Line
End
End Else
Fin = True
End
Until Fin
Repeat
Close UvLoginsFvar
End Else
Error = EADM.CANTOPEN
End
Return
**********************************************************************
* GetUserInfoDetails - Returns the login account details for
* a specified user
*
* Input: user name
* Output: An array of details for the user
**********************************************************************
GetUserInfoDetails:
Ok = 0
Error = 0
Domains = ""
Domain = ""
LocalMachines = ""
LocalMachine = ""
DomainAccount = ""
LocalAccount = ""
Rec = ""
UserInfo = ""
UserId = Params<1>
Lp = 1
* Open the publications files
If DEBUGGING Then
LogText = "UserId :" : UserId
GoSub WriteDbg
End
Open '', "UV.LOGINS" To UvLoginsFvar Then
Read Rec From UvLoginsFvar, UserId Then
* fill in the user description, if any
UserInfo<1> = Rec<5>
* loop pairing up all the domains and their corresponding accounts
Domains = Rec<1>
UserInfo<2> = ""
Loop
Remove Domain From Domains Setting Ok
If Domain Then
DomainAccount = Rec<3,Lp>
* Build the return data array
UserInfo<2,-1> = Domain : @SM : DomainAccount
Lp +=1
End
While Ok Do
Repeat
* reset the Lp counter as we'll reuse it
Lp = 1
* loop pairing up all the local machines and their corresponding accounts
LocalMachines = Rec<2>
UserInfo<3> = ""
Loop
Remove LocalMachine From LocalMachines Setting Ok
If LocalMachine Then
LocalAccount = Rec<4,Lp>
* Build the return data array
UserInfo<3,-1> = LocalMachine : @SM : LocalAccount
Lp +=1
End
While Ok Do
Repeat
* Load the return data with the output
OutData = UserInfo
End Else
Error = EADM.CANTREAD
End
Close UvLoginsFvar
End Else
Error = EADM.CANTOPEN
End
Return
************************************************************************
* GetUVConfig - Returns contents of uvconfig file
*
* Input: NONE
* Output: Parameter info: Param Name
* Param Value
* Param Description
************************************************************************
GetUVConfig:
Open "&UFD&" To UFDFvar Then
Read ConfigData From UFDFvar, UVCONFIG Else
Error = EADM.CANTREAD
End
Close UFDFvar
End Else
Error = EADM.CANTOPEN
End
NumLines = Dcount(ConfigData, @fm)
If NumLines = 0 Then
OutData = ""
Goto ExitGetUVConfig
End
* Ignore header lines - the first line is all '#' characters
* and so is the last line of the header
StartLine = 3
For LineNo = 3 To NumLines
If Trimf(ConfigData<LineNo>) Matches INITIAL$PATTERN Then
StartLine = LineNo + 1
End
Next LineNo
If StartLine = 0 Or StartLine = NumLines Then
Goto ExitGetUVConfig
End
* Now look for all parameters that match the pattern or patterns:
PossStart = 0
PossEnd = 0
For LineNo = StartLine To NumLines
RecLine = ConfigData<LineNo>
IF Trim(RecLine) = '' Then ; * ignore blank lines
Continue
End
If Trimf(RecLine) Matches COMMENT$PATTERN Then
If PossStart = 0 Then
PossStart = LineNo
End
PossEnd = LineNo
Continue
End
* Here, the line must be a parameter
ParamName = Trim(RecLine)
ParamValue = Field(ParamName, ' ', 2)
ParamName= Field(ParamName, ' ', 1)
* Convert all comment text into one big string:
If PossEnd = 0 Then
PossEnd = PossStart
End
ParamDesc = ''
If PossStart > 0 Then
For N = PossStart To PossEnd
ParamDesc := ' ':Trim(ConfigData<N>[2,9999])
Next N
ParamDesc = ParamDesc[2,9999] ; * remove leading space
End
* Save the comment text, the parameter line, etc:
ParamData = ParamName : @vm : ParamValue : @vm : ParamDesc
OutData<-1> = ParamData
PossStart = 0
Next Line
ExitGetUVConfig:
Return
************************************************************************
* GetUVHome - Returns pathname of uv home account
*
* Input: NONE
* Output: uvhome pathname
************************************************************************
GetUVHome:
OutData = UVHOME
Return
**********************************************************************
* GroupList - Returns a list of groups (unix only)
*
* Input: Show group id flag
* Output: Dynamic array of <groupid> <groupname>
* if input flag is true, or <groupname>
* if it is false
**********************************************************************
GroupList:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
ShowGID = Params<1>
FileName = "/etc/group"
Gosub ReadSeqFile
If Error <> False Then
Error = EADM.NOGROUP
Return
End
Dc = Dcount(NewText,@fm)
For I =1 to Dc
If NewText<I>[1,1] <> "+" Then
If ShowGID = True Then
OutData<-1> =NewText<I>[":",3,1]:" ":NewText<I>[":",1,1]
End Else
OutData<-1> = NewText<I>[":",1,1]
End
End
Next
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* ChangeToFiles -
*
*
*
*
* Input:
* Output:
*
**********************************************************************
ChangeToFiles:
chgtype = Params<1>
ExLine = "CHG.RAWOVER ":chgtype
Gosub TCLCommand
If Out # "" Then
Begin Case
Case Out[1,2] = "37" ; * Change to files failed
Error = EADM.CHANGEFAILED
Case Out[1,2] = "38"
Error = EADM.CHANGEFLFAILED ; * Change to Raw failed
Case 1
* success
End Case
If DEBUGGING Then
LogText = "Error = ":Error
Gosub WriteDbg
End
End
If DEBUGGING Then
LogText = "Error inside ChangeToFiles = ":Error
Gosub WriteDbg
End
Return
**********************************************************************
* IdentifyLogs - Gets highest and lowest checkpointed logs
* required to recover the selected files. Return
* an error if the select list name is invalid,
* or return null if we can't get the information
*
* Input: File selection: ALL or select list name
* Output: Lowest log number
* Highest log number
**********************************************************************
IdentifyLogs:
Selection = Trim(Params<1>)
ExLine = "RECOVERY.CHECKPOINT " : Selection : " 1"
Gosub TCLCommand
* RECOVERY.CHECKPOINT can return the following:
* -1 to indicate select list name was invalid
* -2 to indicate UV.TRANS file open failed
* -3 to indicate unable to read from UV.TRANS
* -4 to indicate unable to open DICT UV_LOGS
* -5 to indicate unable to read from DICT UV_LOGS
* or LowMark : @fm : HighMark
* if both the first log and last log are zero, then no
* checkpoint information is available.
Temp = Trim(Out<1>)
retry.rec.chkpt:
If Count(Temp, @vm) = 1 Then ; * it worked
If Temp<1,1> = 0 And Temp<1,2> = 0 Then
Error = EADM.NOCPINFO
End Else
OutData = Temp<1,1> : @fm : Temp<1,2>
End
End Else
* It maybe that the log files are full and a warning was on the
* first line
If Temp = "Error getting first empty log." then
Temp = Trim(Out<2>)
Goto retry.rec.chkpt
End
* It failed - return an error if the select list was bad, otherwise
* return null
If Temp = -1 Then
Error = EADM.BADSELECTNAME
End Else
Error = EADM.NOCPINFO
End
End
Return
***********************************************************************
* Initialise - Opens files and sets up debugging if required
*
* Input: NONE
* Output: UVHome path
* OSExec command
***********************************************************************
Initialise:
Open 'VOC' To VOC Else
Error = EADM.NOVOC
Return
End
* Look for VMADMDBG record in VOC. If it's present, switch DEBUGGING on
Read Rec From VOC, "VMADMDBG" Then
DEBUGGING = True
End Else
DEBUGGING = False
End
If DEBUGGING Then
DebugFile = "./Debug_":@UserNo
OpenSeq DebugFile To DEBUGFL Else
Create DEBUGFL Else
DEBUGGING = False
End
Seek DEBUGFL, -1, 2 Else Null
LogText = Oconv(Date(), "D2/"):" ":Oconv(Time(), "MTS")
GoSub WriteDbg
End
End
If DEBUGGING Then
LogText = "Initialising"
GoSub WriteDbg
End
* Before doing anything else, check that user is an administrator
Temp = ""
call *ISUSER.B(0, Temp)
If Temp = 0 Then
Error = EADM.NOTADMIN
Return
End
Open 'UV.ACCOUNT' To UVACCOUNT Else
Error = EADM.NOUVACCOUNT
Return
End
UVHOME = System(32)
UVHOMEBIN = UVHOME:OS.SEP:"bin":OS.SEP
Open '&DEVICE&' To DEVICES Else
Error = EADM.NODEVICE
Return
End
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
* Initialise spooler variables eg. spool directory
GoSub InitSpooler
End
************************
* OS specific code end *
************************
UVRC.OPEN = False
OutData = UVHOME : @fm : OS.EXEC
Return
**********************************************************************
* JobDets - Returns modifiable information about a job
* on a printer queue. NOTE: doesn't return
* printer because the client already knows this
* Unix only
*
* Input: Job number
* Output: Copies
* Retain flag
* Form
* Priority
* Start page
* End page
* Start line
* End line
* Delay (hours)
* Delay (minutes)
**********************************************************************
JobDets:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
GoSub SpStatuses
JobNo = Params
GoSub GetSpoolDetails
If Error <> False Then
Return
End
* Check job still exists
Locate Params<1> In JobIndex Setting Pos Else
Error = EADM.NOPRINTJOB
Return
End
Line = Raise(JobList<Pos>)
OutData = Line<USPJ.COPIES>
OutData<2> = Line<USPJ.HOLD>
OutData<3> = Line<USPJ.FORM>
OutData<4> = Line<USPJ.PRIORITY>
OutData<5> = Line<USPJ.STARTPG>
OutData<6> = Line<USPJ.ENDPG>
OutData<7> = Line<USPJ.STARTLINE>
OutData<8> = Line<USPJ.ENDLINE>
UspDelay = Line<USPJ.TIMER>
GoSub GetDelayTime
OutData<9> = Hours
OutData<10> = Mins
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* ListActiveFiles - Returns status information for files which
* have been activated for transaction logging
*
* Input: NONE
* Output: Dynamic array of Active file info:
* TLnum
* Account
* File
* Status
* Pathname
**********************************************************************
ListActiveFiles:
Open '', "UV.TRANS" To UvTransFvar Then
SSelect UvTransFvar
Fin = False
Loop
Readnext Id Then
Read Rec From UvTransFvar, Id Then
Account = Rec<1>
File = Rec<2>
If Rec<3> = 0 Then
FileStatus = ""
End Else
FileStatus = "Active"
End
Path = Rec<4>
Line = Id : @vm : Account : @vm : File : @vm : FileStatus
Line := @vm : Path
OutData<-1> = Line
End
End Else Fin = True
Until Fin
Repeat
Close UvTransFvar
End Else
Error = EADM.CANTOPEN
End
Return
**********************************************************************
* ListDeadLocks - Returns the Lock information
*
* Input: None
* Output: Current Dead Locks
**********************************************************************
ListDeadLocks:
NumLines = 0
Error = 0
Index = 0
Line = ""
OutData = ""
* Use the -query option to return the current deadlocks
ExLine = UVHOMEBIN:"uvdlockd -query"
Gosub ShellCommand
NumLines = DCount(Out, @fm)
For Index = 1 To NumLines
Line = Out<Index>
Line = Trim(Line)
If Line[1,7] = "No dead" Then
OutData = ""
End
Else
If Line[1,4] = "User" Then
Line = Field(Line, " ", 2):@VM:Field(Line," ", 3, 99)
OutData<-1> = Line
End
End
Next Index
Return
***********************************************************************
* ListLocks - Returns file, group and record lock
* information
*
* Input: NONE
* Output: File lock data
* Record lock data
* Group lock data
***********************************************************************
ListLocks:
ExLine = "list_readu EVERY INTERNAL"
GoSub UvCommand
FileData = ""
RecData = ""
GroupData = ""
* The INTERNAL keyword to list_readu causes it to return output
* separated by mark characters (ie. almost in the format that we want it)
* all we have to do is figure out what type of lock each line is
* detailing. Do this by the number of values contained in the line -
* NOTE that the last value is usually null (bad lock)
* Then create the Lmode value by combining the lock semaphore
* number with the type.
NumLines = Dcount(Out, @fm)
For Index = 1 To NumLines
Line = Out<Index>
If Trim(Line) <> "" Then
NumValues = Dcount(Line, @vm)
* Replace 5th value mark with a space - this gives us the
* correct format for Lmode
Line = Change(Line, @vm, " ", 1, 5)
Begin Case
Case NumValues = 9 ; * File lock
FileData<-1> = Line
Case NumValues = 10 ; * Record lock
RecData<-1> = Line
Case NumValues = 12 ; * Group lock
GroupData<-1> = Line
End Case
End
Next Index
OutData = Lower(FileData):@fm:Lower(RecData):@fm:Lower(GroupData)
Return
**********************************************************************
* LogControl - Changes the state of transaction logging
* If transaction logging is to be enabled,
* a check will be done to see if synchronisation
* is required. If it is required, an error will
* be returned so that the client can prompt the
* user. If the user wishes to synchronise, then
* this function will be called a second time, with
* an extra parameter. The Synchronise parameter
* will not be present on the first call.
*
* Input: Key: 1 - enable logging
* 2 - suspend logging
* 3 - shutdown logging
* RetainInfoFile (if Key = 1)
* Synchronise (if Key = 1)
* Output: NONE
**********************************************************************
LogControl:
ControlKey = Params<1>
State = ""
RECIO(State, FINFO$AI.STATE, RECIO$FINFO)
Begin Case
Case ControlKey = 1 ; * Enable logging
* Don't allow enable if a) it is already enabled, or b) it is in
* the process of being enabled or c) it is being shutdown or
* suspended
Retain = Params<2>
Synchronise = Params<3> ; * Will be set to 1 if this is the 2nd call
If State # AI$SHUT.PROG and State # AI$SUSP.PROG And State # AI$LOGGING And State # AI$INITIAL And State # AI$WARM.START Then
* Check if we need to synchronise. Do this even if this is
* the second call and Synchronise is set as the situation
* may have changed inbetween the calls.
* If checkpointing is on and in Full state and at least one
* log file state is NeedsSync and no log Avail, then return
* error so that the client can ask whether to destroy stale
* transactions
If State = AI$FULL Then
NeedsSync = False
ExLine = "SELECT UV_LOGS WITH STATUS = Available"
Gosub TCLCommand
If @SELECTED > 0 Then Goto EndSyncCheck
ExLine = "SELECT UV_LOGS With STATUS = Full"
Gosub TCLCommand
If @SELECTED > 0 Then Goto EndSyncCheck
Open 'DICT', "UV_LOGS" To UvLogFvar Then
Read Rec From UvLogFvar, "CHECKPOINT" Then
If Rec<2> = "TRUE" Then
ExLine = "SELECT UV_LOGS With STATUS = NeedsSync"
Gosub TCLCommand
If @SELECTED > 0 Then
NeedsSync = True
End
End
End
End
* If synchronisation is required and this is the first call
* (ie. Synchronise is not set), return an error. If Synchronise
* is set but we no longer need it, clear it.
If NeedsSync Then
If Synchronise # 1 Then
Error = EADM.NEEDSYNC
Return
End
End Else
Synchronise = ""
End
End
EndSyncCheck:
If Retain = 1 Then
ExLine = "ENABLE.RECOVERY YES"
End Else
ExLine = "ENABLE.RECOVERY NO"
End
If Synchronise = 1 Then
ExLine := " SYNC"
End
Gosub TCLCommand
End
Case ControlKey = 2 ; * Suspend logging
If State = AI$LOGGING Then
ExLine = "SUSPEND.RECOVERY"
Gosub TCLCommand
End
Case ControlKey = 3 ; * Shutdown logging
If State = AI$INITIAL Or State = AI$WARM.START Or State = AI$LOGGING Or State = AI$SUSPENDED Or State = AI$FULL Then
ExLine = "SHUTDOWN.RECOVERY"
Gosub TCLCommand
End
End Case
Return
**********************************************************************
* LogFileInfo - Returns current log file information
*
* Input: NONE
* Output: Total space
* Available space
* Current log file
* Dynamic array of log info:
* Logfile name
* Start date
* Start time
* Full date
* Full time
* Size
* State
**********************************************************************
LogFileInfo:
* Get current log number
FileNo = ""
RECIO(FileNo, FINFO$AI.SEQUENCE, RECIO$FINFO)
CurrLogFile = FileNo
* Go through the UV_LOGS file getting logfile data and calculating
* space available - don't include released log files in the space
* calculations
Fin = False
Sum = 0
Full = 0
LogFileData = ""
Offset = 0
Open '', "UV_LOGS" To UvLogFvar Then
ExLine = "SELECT UV_LOGS BY.DSND @ID"
Gosub TCLCommand
Loop
Readnext Id From SList Then
Read Rec From UvLogFvar, Id Then
StartDate = Oconv(Rec<AIF.CURR.DATE>, "D2")
StartTime = Oconv(Rec<AIF.CURR.TIME>, "MTS")
FullDate = Oconv(Rec<AIF.FULL.DATE>, "D2")
FullTime = Oconv(Rec<AIF.FULL.TIME>, "MTS")
Size = Rec<AIF.SIZE>
LogStatus = Rec<AIF.STATUS>
Offset = Rec<AIF.OFFSET>
If LogStatus # "R" Then
Sum += Size
If LogStatus = "F" Or LogStatus = "N" Then
Full += Size
End
End
Begin Case
Case LogStatus = "R"
LogStatus = "Released"
Case LogStatus = "A"
LogStatus = "Available"
Case LogStatus = "C"
LogStatus = "Current"
Case LogStatus = "N"
LogStatus = "NeedsSync"
Case LogStatus = "F"
LogStatus = "Full"
Case LogStatus = "E"
LogStatus = "Error"
Case 1
LogStatus = "Unknown"
End Case
Line = Id : @vm : StartDate : @vm : StartTime : @vm : FullDate
Line := @vm : FullTime : @vm : Size : @vm : LogStatus : @vm : Offset
LogFileData<-1> = Line
End
End Else Fin = True
Until Fin
Repeat
Avail = Sum - Full
Close UvLogFvar
End Else
Error = EADM.CANTOPEN
End
OutData = Sum
OutData<-1> = Avail
OutData<-1> = CurrLogFile
OutData := @fm : LogFileData
Return
**********************************************************************
* Logout - Logout a UniVerse user and clean up shared
* memory for that user. This is done using
* "master OFF" for both unix and NT. On unix,
* if this fails, then a kill -15 is attempted.
* On unix, phantoms have to be logged out using
* kill -15 because they don't have a UniVerse
* user number.
*
* Input: UniVerse user number (null if phantom)
* PID
* Output: NONE
**********************************************************************
Logout:
UserId = Trim(Params<1>)
Pid = Trim(Params<2>)
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
* Can't user MASTER OFF if we're logging out a phantom process as
* we don't have its UniVerse user number
If UserId = "" Then
Goto Kill15
End
End
************************
* OS specific code end *
************************
ExLine = "master OFF " : UserId
Gosub UvCommand
Gosub CheckUserGone
If Found = False Then
Out = ''
Return ; * termination successful
End
Kill15:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
* On unix, users can also be logged out using "kill -15". To get here,
* either we are logging out a phantom, or the MASTER OFF command
* failed to log the user out
If Pid = '' Then
Out = ''
Return
End
ExLine = "kill -15 ":Pid
GoSub ShellCommand
Gosub CheckUserGone
If Found = False Then
Out = ''
Return
End
GoSub CleanUser ; * Belt and braces
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* MagrstCommand - Set up command line for magrst
*
* Input: Restore directory
* Device name
* Block size
* Use Type19 flag
* Output: Command line
**********************************************************************
MagrstCommand:
RstPath = Params<1>
DevName = Params<2>
BlockSize = Params<3>
Type19 = Params<4>
* Check that restore directory can be written to
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
If access(RstPath, W$OK + R$OK) Then
Error = EADM.NOACCESS
Goto ExitMagrstCommand
End
End
************************
* OS specific code end *
************************
* Get device pathname from &DEVICE& file
Read DevRec From DEVICES, DevName Else
Error = EADM.CANTREAD
Goto ExitMagrstCommand
End
DevPath = DevRec<2>
DevType = DevRec<4>
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
ExLine = "ls -l " : DevPath
Gosub ShellCommand
If Out[1, 3] # "crw" Then
Error = EADM.BADDEVICE
Goto ExitMagrstCommand
End
End
************************
* OS specific code end *
************************
* Validation finished, set up the command line
Command = OS.CD : RstPath : OS.CMDSEP
Command := " " : UVHOMEBIN : "tapein -ice"
Command := " -p" : UVHOMEBIN : "magrst"
Command := " -f" : DevPath
Command := " -b" : BlockSize
If Type19 Then
Command := " -t"
End
If DevType = "C" Or DevType = "DC" Then
Command := " -c"
End
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Command := " -a"
End
************************
* OS specific code end *
************************
ExitMagrstCommand:
If Error = 0 Then
OutData = OS.EXEC : " " : Quote(Command)
End
Return
**********************************************************************
* MakeAccount - Adds the account to the UV.ACCOUNT file and
* creates a new account if one doesn't already
* exist in the directory.
*
* Input: Account Name
* Parent directory
* Flavor
* Use default LOGIN paragraph flag
* Owner (unix only)
* Group (unix only)
* Use default permissions flag (unix only)
* Permissions (null if using default) (unix only)
* Output: Status value: 0 - Account created
* 1 - Account already exists
* in the directory
* 2 - Directory already exists
**********************************************************************
MakeAccount:
Name = Params<1>
PathName = Params<2>
Flavor = Params<3>
UseDfltLogin = Params<4>
PathOwner = ""
PathGroup = ""
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Owner = Params<5>
Group = Params<6>
UseDfltPerms = Params<7>
Perms = Params<8>
* Set up umask: if using default permissions, set them up,
* otherwise use what was passed in (after converting it into a number)
If UseDfltPerms Then
PermissionNum = DEFPERMS
End Else
If Num(Perms) = 1 Then
PermissionNum = Perms
End Else
GoSub ConvertPermissions
End
End
Umask = 777 - PermissionNum
End
************************
* OS specific code end *
************************
GoSub CheckPathName ; * Checks validity of pathname
If PathOk = False Then
Error = EADM.BADPATH
Return
End
* Check if pathname already exists & if so, whether there is already an
* account there
PathExists = False
VocExists = False
ReturnStatus = 0 ; * Assume creating the account
OpenPath PathName To PathVar Then
Status PathStatus From PathVar Then
PathOwner = PathStatus<8> ; * used by unix code only
PathGroup = PathStatus<9> ; * used by unix code only
End
Close PathVar
PathExists = True
ReturnStatus = 2 ; * Directory exists
OpenPath PathName:OS.SEP:"VOC" Then
Close
VocExists = True
ReturnStatus = 1 ; * Account exists
End
End
If PathExists = False Then ; * create path
ExLine = "mkdir ":PathName
GoSub ShellCommand
ExLine = OS.CD:PathName
GoSub ShellCommand
If Trim(Out) <> "" Then
Error = EADM.NOCREATEDIR
Return
End
End
If VocExists = False Then ; * create account
ExLine = OS.CD:PathName:OS.CMDSEP
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
ExLine := "umask ":Umask:OS.CMDSEP
End
************************
* OS specific code end *
************************
ExLine := UVHOMEBIN:"mkaccount ":Flavor
GoSub ShellCommand
OpenPath PathName:OS.SEP:"VOC" To VocFvar Then
If UseDfltLogin Then
OpenPath UVHOME:OS.SEP:"sample" To Temp Then
Read LoginPara From Temp, "LOGIN" Then
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
LoginPara<-1> = "UMASK ":Umask
End
************************
* OS specific code end *
************************
If Flavor = "PICK" Then
Write LoginPara To VocFvar, Name
End
Else
Write LoginPara To VocFvar, "LOGIN"
End
End
Close Temp
End
End
Close VocFvar
End
Else
Error = EADM.NOMAKEACCOUNT
Return
End
End
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
* If we have created the whole directory, set th permissions &
* ownership of everything in that directory. If we just created
* the account in an existing directory, make the account files
* have the same owner & group as the directory
If PathExists = False Then
Params = PathName:@fm:Owner:@fm:Group
Gosub Chown
ExLine = 'find ':PathName:' -exec chmod ':PermissionNum:' {} \;'
GoSub ShellCommand
End
Else
If PathOwner <> "" And PathGroup <> "" Then
Params = PathName:@fm:PathOwner:@fm:PathGroup
Gosub Chown
End
End
End
************************
* OS specific code end *
************************
WriteV PathName On UVACCOUNT,Name,11 ; * Write to UV.ACCOUNT file
OutData = ReturnStatus
Return
**********************************************************************
* Message - Send a message to a user or users. The user(s)
* can be specified in several ways:
* User name - sends to that user (Unix & NT)
* Tty - sends to user on that port (Unix only)
* User no - sends to that user number (NT only)
* Domain - sends to all users on that domain
* (NT only)
* * - sends to all users (Unix & NT)
* null - sends to system console (Unix only)
* On unix, the message goes to all logged in users
* who match the specified selection. On NT, the
* message goes to all UniVerse users who match the
* specification.
*
* Input: User specification
* Message
* Output: NONE
**********************************************************************
Message:
User = Params<1>
Msg = Params<2>
If Msg <> "" Then
ExLine = "MESSAGE " : User : " -MSG '" : Msg : "'"
Gosub TCLCommand
End
Return
**********************************************************************
* MessUsers - Returns list of user names of interactive
* UniVerse users (ie. those who can be sent a
* message
*
* Input: NONE
* Output: List of user names
**********************************************************************
MessUsers:
* Use the INTERNAL keyword to PORT.STATUS which produces us
* value mark separated data
ExLine = "PORT.STATUS INTERNAL"
Gosub TCLCommand
* PORT.STATUS can only be used by one person at a time
if index(Out,"PORT.STATUS is currently being run",1) Then
Error = EADM.INUSE
End
* First line of data returned contains counts of users
NumInteractive = Trim(Out<1,2>)
If NumInteractive > 0 Then
For Index = 2 To NumInteractive + 1 ; * skip summary line
* Only add this user to the list if they're not already there
User = Trim(Out<Index, 2>)
FindStr User In OutData Setting Fmc Else
OutData<-1> = User
End
Next Index
End
Return
**********************************************************************
* ModSpoolJob - Changes job details using usm. Fields in input
* parameter will only contain data if that job
* characteristic has been changed
* Unix only
*
* Input: Job ID
* Copies
* Retain flag
* Printer
* Form
* Priority
* Page range
* Line range
* Defer - +hours:minutes (relative)
* +minutes (relative)
* hours:minutes (absolute)
* minutes (absolute)
* Output: NONE
**********************************************************************
ModSpoolJob:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
JobNo = Params<1>
Copies = Params<2>
Retain = Params<3>
Printer = Params<4>
Form = Params<5>
Priority = Params<6>
PageRange = Params<7>
LineRange = Params<8>
DeferTime = Params<9>
GoSub CheckSpooler
If Error # 0 Then
Return
End
If Copies <> "" Then
ExLine = USM.PATH:" -n ":Copies:" ":JobNo
GoSub ShellCommand
End
If Retain <> "" Then ; * cannot cancel retain
ExLine = USM.PATH : " -q ":JobNo
GoSub ShellCommand
End
If Printer <> "" Then
ExLine = USM.PATH:" -p ":Printer:" ":JobNo
GoSub ShellCommand
End
If Form <> "" Then
ExLine = USM.PATH
If Upcase(Form) = "[NULL]" Then
Form = '""'
End
ExLine := " -F ":Form:" ":JobNo
GoSub ShellCommand
End
If Priority <> "" Then
ExLine = USM.PATH:" -P ":Priority:" ":JobNo
GoSub ShellCommand
End
If PageRange <> "" Then
ExLine = USM.PATH:" -x ":PageRange:" ":JobNo
GoSub ShellCommand
End
If LineRange <> "" Then
ExLine = USM.PATH:" -y ":LineRange:" ":JobNo
GoSub ShellCommand
End
If DeferTime <> "" Then
ExLine = USM.PATH:" -t ":DeferTime:" ":JobNo
GoSub ShellCommand
End
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* NetReleaseLocks - Releases locks held on network services files
*
* Input: NONE
* Output: NONE
**********************************************************************
NetReleaseLocks:
Close ETC.FVAR
Return
**********************************************************************
* OSBrowse - Returns a list of the directories and files
* contained in a specified directory.
*
* The directory to list is determined by
* combining the two input arguments, start
* directory and directory modifier.
*
* Example 1:
*
* Start directory = "/u1/uv"
* Modifier = ".."
*
* Directory listed will be "/u1"
*
* Example 2:
*
* Start directory = "/u1/uv"
* Modifier = "catdir"
*
* Directory listed will be "/u1/uv/catdir"
*
* If the start directory is not specified, then
* the UVHOME directory is used as a default
*
* If the start directory turns out to be a file,
* or if it doesn't exist, then the last component
* of the pathname is removed, and the parent
* directory is listed. If that doesn't exist,
* an error is returned.
*
* Input: Start directory
* Directory modifier
* Output: Modified directory
* List of directories (prefixed by "D") and
* files (prefixed by "F")
**********************************************************************
OSBrowse:
BrowsePath = Trim(Params<1>)
Modifier = Trim(Params<2>)
BrowsePath = Change(BrowsePath, OS.SEP:OS.SEP, OS.SEP)
If BrowsePath <> "" then
Begin Case
Case Modifier = ".." ; * going up a level
BrowsePath = BrowsePath[OS.SEP, 1, Count(BrowsePath, OS.SEP)]
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
* If we've gone back so far that there's nothing left, set
* path to root
If BrowsePath = "" Then
BrowsePath = OS.SEP
End
End Else
* If we've gone so far back we've stripped the separator from
* the drive, put it back
If Len(BrowsePath) = 2 And BrowsePath[2, 1] = ":" Then
BrowsePath := OS.SEP
End
End
************************
* OS specific code end *
************************
Case Modifier = "" ; * no modifier, do nothing
Case 1
* Going down a level. If we're at the top (eg. "/" or "d:\")
* then we don't need to put the separator in
If BrowsePath[Len(BrowsePath), 1] <> OS.SEP Then
BrowsePath := OS.SEP:Params<2>
End Else
BrowsePath := Params<2>
End
End Case
End Else
BrowsePath = UVHOME
End
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
* Request a single column listing with directories suffixed with "/".
* If the pathname does not specify a directory, the result
* will start with the input pathname exactly
ExLine = 'ls -p "':BrowsePath:'"'
GoSub ShellCommand
If Out[1, Len(BrowsePath)] = BrowsePath Then
* Modify the path and try again
BrowsePath = BrowsePath[OS.SEP, 1, Count(BrowsePath, OS.SEP)]
* If we've gone back so far that there's nothing left, set
* path to root
If BrowsePath = "" Then
BrowsePath = OS.SEP
End
ExLine = 'ls -p "':BrowsePath:'"'
GoSub ShellCommand
If Out[1, Len(BrowsePath)] = BrowsePath Then
* Failed again - return an error
Error = EADM.NODIRECTORY
Return
End
End
End Else ; * NT
* First try to get the list of directories. This will return
* an error message:
* - "File Not Found" if the parent directory exists but
* the file either doesn't exist or is not a directory
* - "The system cannot find the file specified." or
* "The system cannot find the path specified." if the
* parent directory doesn't exist.
* - "The filename, directory name, or volume label syntax is incorrect" if
* any part of the pathname is incorrect.
* These tests only work if the language is English. For the
* future, we should devise a language-indpendent way of doing
* the browse function.
ExLine = 'dir /B/AD "':BrowsePath:'"'
GoSub ShellCommand
CheckString = "The filename, directory name, or volume label syntax is incorrect"
If Out[1, Len(CheckString)] = CheckString Then
* Invalid pathname, so give up
Error = EADM.NODIRECTORY
Return
End
CheckString = "The system cannot find the "
If Out[1, Len(CheckString)] = CheckString Then
* The parent directory doesn't exist, so give up
Error = EADM.NODIRECTORY
Return
End
CheckString = "File Not Found"
If Out[1, Len(CheckString)] = CheckString Then
* Modify the path and try again
BrowsePath = BrowsePath[OS.SEP, 1, Count(BrowsePath, OS.SEP)]
* If we've gone so far back we've stripped the separator from
* the drive, put it back
If Len(BrowsePath) = 2 And BrowsePath[2, 1] = ":" Then
BrowsePath := OS.SEP
End
ExLine = 'dir /B/AD "':BrowsePath:'"'
GoSub ShellCommand
If Out[1, Len(CheckString)] = CheckString Then
If Len(BrowsePath) = 3 And BrowsePath[2, 2] = ":":OS.SEP Then
* No files in root directory - return an empty directory listing
OutData = BrowsePath:@fm:"D.."
Return
End Else
* Failed again - return an error
Error = EADM.NODIRECTORY
Return
End
End
End
End
************************
* OS specific code end *
************************
* Because we don't get the parent directory returned by "ls" or
* "dir", put it in by hand
OutData = BrowsePath:@fm:"D.."
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
* Use a single column listing with directories suffixed with "/".
* The listing we need is already in the variable "Out"
Dc = Dcount(Out,@fm)
For I = 1 To Dc
If Out<I> <> "" then
File = Trim(Out<I>)
If File[Len(File), 1] = "/" Then
OutData<-1> = "D":File[1, Len(File) - 1]
End Else
OutData<-1> = "F":File
End
End
Next
End Else ; * NT
* First use the list of directories. This is already in the
* variable "Out".
Dc = Dcount(Out,@fm)
For I = 1 To Dc
If Out<I> <> "" Then
OutData<-1> = "D":Trim(Out<I>)
End
Next
* Now get the list of files, excluding hidden files
ExLine = 'dir /B/A-D-H "':BrowsePath:'"'
GoSub ShellCommand
CheckString = "File Not Found"
If Out[1, Len(CheckString)] # CheckString Then
Dc = Dcount(Out, @fm)
For I = 1 To Dc
If Out<I> <> "" Then
OutData<-1> = "F":Trim(Out<I>)
End
Next
End
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* ParseRestoreLabel - Parse uvrestore output, obtained from
* CheckRestoreSource function, to extract
* data about the backup tape
*
* Input: uvrestore output from earlier call
* to CheckRestoreSource
* Output: Dynamic array of backup info, as
* follows:
* 1 Backup Date
* 2 Reel number
* 3 Compression flag
* 4 Image Type
* 5 Block Size
* 6 Image Label
* 7 NLS enabled flag
* 8 NLS OS map name
**********************************************************************
ParseRestoreLabel:
OutField = 1 ; * Backup Date
Msg = 85400
GoSub ExtractRestoreLabelField
OutField = 2 ; * Reel Number
Msg = 85401
GoSub ExtractRestoreLabelField
OutField = 3 ; * Compression flag
Msg = 85402
GoSub ExtractRestoreLabelField
OutField = 4 ; * Image Type
Msg = 85403
GoSub ExtractRestoreLabelField
OutField = 5 ; * Block Size
Msg = 85459
GoSub ExtractRestoreLabelField
OutField = 6 ; * Image Label
Msg = 85404
GoSub ExtractRestoreLabelField
* The label may extend over 2 lines
If Params<LineNo+1>[1, 1] = " " Then
OutData<6> = OutData<6> : TrimB(TrimF(Params<LineNo+1>))
End
OutField = 7 ; * NLS enabled flag
Msg = 85503
GoSub ExtractRestoreLabelField
OutField = 8 ; * NLS OS map
Msg = 85504
GoSub ExtractRestoreLabelField
Return
**********************************************************************
* PurgeDeadLock - Purges the Lock Log specified
*
* Input: Log Path
* Output: Log data
**********************************************************************
PurgeDeadLockLog:
ReturnCode = 0
* Pathname from client
LogFile = Trim(Params):OS.SEP:"uvdlockd.log"
OpenSeq LogFile To Flog Locked
ReturnCode = EADM.RECLOCKED
End
Then
* Use writeeof to put an end of file at the begining of the file
* to truncate the rest of the data.
WeofSeq Flog
CloseSeq Flog
End
Else
ReturnCode = EADM.NOFILE
End
Error = ReturnCode
Return
**********************************************************************
* PurgeLogFiles - Purges released log files whose
* "full" date is earlier than the date given
*
* Input: Date string (MM/DD/YY)
* Output: Number of files purged
**********************************************************************
PurgeLogFiles:
InDate = Params<1>
If Not(InDate Matches '2n/2n/0n') Then
Error = EADM.INVALIDDATE
Return
End
CurrDate = Iconv(InDate, "D")
SelDate = Oconv(CurrDate, "D2/")
ExLine = "SSELECT UV_LOGS WITH STATUS = Released AND FULL.DATE < " : SelDate
Gosub TCLCommand
Fin = False
Counter = 0
* Need to make a list of the lognumbers to purge, then go through
* and delete them, rather than delete each one as we find it. This
* stops SList being overwritten by the execution of the delete
PurgeList = ""
Loop
ReadNext Id From SList Then
PurgeList<-1> = Id
Counter += 1
End Else
Fin = True
End
Until Fin
Repeat
For Index = 1 To Counter
ExLine = "DELETE UV_LOGS " : PurgeList<Index>
Gosub TCLCommand
Next Index
OutData = Counter
Return
*********************************************************************
* PutDevice - Writes a device record to &DEVICE&. For
* unix systems, if the device is a printer
* definition, also updates the sp.config file
*
* Input: Device name
* Device data
* Output: NONE
*********************************************************************
PutDevice:
DevName = Params<1>
DevRec = Params[@fm, 2, 9999]
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
DevType = DevRec<4>
If DevType[1,1] = "P" Then
Gosub PutPrinter
End
End
************************
* OS specific code end *
************************
If Error = 0 Then
Write DevRec On DEVICES, DevName Else
Error = EADM.CANTWRITE
End
End
Return
********************************************************************
* ReleaseLock - Releases a lock
*
* Input: Type of lock: 1 - group lock
* 2 - record lock
* 3 - file lock
* Device
* Inode
* Netnode
* User
* Type
* RecId or Group Address or null
* Output: NONE
********************************************************************
ReleaseLock:
LockType = Params<1>
Device = Params<2>
Inode = Params<3>
Netnode = Params<4>
User = Params<5>
Type = Params<6>
If LockType = GROUPLOCK Then
GroupAddr = Params<7>
End Else
* File or record lock, to determine which, see if we have a
* record id. If there is no record id, it must be a file lock
RecId = Params<7>
If RecId = "" Then
LockType = FILELOCK
End
End
* Set up the UNLOCK command - all three types of unlock start the
* same:
ExLine = "UNLOCK DEVICE ":Device:" INODE ":Inode:" NODE ":Netnode
Begin Case
Case LockType = GROUPLOCK ; * convert group address from hex
ExLine := " GROUP ":OConv(GroupAddr,"MCX"):" GROUPLOCK"
Case LockType = RECORDLOCK ; * specify id and type of read lock
ExLine := " RECORD ":RecId
If index(Type,"RU",1) Then
ExLine := " READULOCK"
End Else
ExLine := " READLLOCK"
End
Case LockType = FILELOCK ; * add "FILELOCK" keyword
ExLine := " FILELOCK"
End Case
Gosub TCLCommand
Return
**********************************************************************
* ReleaseLogFiles - Releases one or more full log files or a
* single tape log
*
* Input: Key: 1 - Disk log file
* 2 - Tape log
* First log file number/Device
* Last log file number (optional)
* Output: NONE
**********************************************************************
ReleaseLogFiles:
Key = Params<1>
If Key = 1 Then
FirstLog = Params<2>
If Trim(Params<3>) = "" Then
LastLog = FirstLog
End Else
LastLog = Params<3>
End
For Index = FirstLog To LastLog
ExLine = "RELEASE.LFILE " : Index
Gosub TCLCommand
If Out <> "" Then
Error = EADM.NORELEASE
OutData = Trim(Out)
End
Next Index
End Else
DevName = Params<2>
Readu Rec From DEVICES, DevName Then
If Rec<18> = "LG_FULL" Then
Rec<18> = ""
Write Rec To DEVICES, DevName Else
Error = EADM.CANTWRITE
End
End
End Else
Error = EADM.CANTREAD
End
End
Return
********************************************************************
* ReleaseUserLocks - Release all locks owned by a specified
* user
*
* Input: User No
* Output: NONE
********************************************************************
ReleaseUserLocks:
ExLine = "UNLOCK USER " :Params<1>:" ALL"
Gosub TCLCommand
Return
********************************************************************
* RemoveBackupTarget - Remove a disk file before starting a backup
* to that pathname
*
* Input: File pathname
* Output: Any error message generated
********************************************************************
RemoveBackupTarget:
ExLine = OS.EXEC : " '" : RM.CMD : " " : Params<1> : "'"
Gosub TCLCommand
OutData = Out
Return
**********************************************************************
* RepAccountList - Returns list of accounts on the server
*
* Input: NONE
* Output: Field mark separated list of accounts
* <X,1>Account Name
* <X,2>Pub State
* <X,2>Sub State
**********************************************************************
RepAccountList:
PubState = 0
SubState = 0
SSelect UVACCOUNT
Done = False
Loop
ReadNext Id Else Done = True
Until Done Do
* we remove the duplicate UniVerse account entry in UVACCOUNTS
If Id <> "uv" Then
OutData<-1> = Id : @VM : PubState : @VM : SubState
PubState = 0
SubState = 0
End
Repeat
NumAccounts = Dcount(OutData,@FM)
For i = 1 To NumAccounts
* check for pub state
EXECUTE "SELECT UV_UDRPUB WITH ACCOUNT EQ " : OutData<i,1> : " SAVING UNIQUE ACCOUNT"
ReadNext Id Then OutData<i,2> = 1 Else OutData<i,2> = 0
* check for sub state
EXECUTE "SELECT UV_UDRSUB WITH ACCOUNT EQ " : OutData<i,1> : " SAVING UNIQUE ACCOUNT"
ReadNext Id Then OutData<i,3> = 1 Else OutData<i,3> = 0
Next
Return
**********************************************************************
* RepAddRepSystem - Adds a new subscriber systems definition
*
* Input: Details Details
* Output: Rep System Key
**********************************************************************
RepAddSystem:
SysKey = ""
Error = 0
SystemArray = ""
Key = ""
SystemName = ""
ConId = ""
MachineName = ""
Dim CALL.ARGS(10,2)
Dim RES.ARGS(20,2)
SystemName = Trim(Params<1>)
Open "","UV_UDRSYS" To UvSysFvar Then
EXECUTE "SELECT UV_UDRSYS WITH STATE_TYPE EQ '' AND WITH @ID NE 'HOTBACKUP'"
Loop
Readnext Key Else NULL
While Key Do
Read SystemArray From UvSysFvar, Key Then
If Trim(Upcase(SystemArray<1>)) = Upcase(SystemName) Then
Error = EADM.ALREADYEXISTS
Exit
End
End
Repeat
* See if we can open the system and see if the udr service is on it.
If Not(Error) Then
ConId = RPC.CONNECT(SystemName, UDR.SERVICE)
If ConId Then
* Make call to add the system as hotbackup to the remote
If Params<5> Then
* Get the Hostname
ExLine = HOSTNAME
Gosub ShellCommand
MachineName = Trim(Out<1>)
CALL.ARGS(1,1) = UDR.SRV.ADDHOTBACKUPSYS ; * Add hot backup sys
CALL.ARGS(1,2) = UVRPC.INT
CALL.ARGS(2,1) = MachineName
CALL.ARGS(2,2) = UVRPC.STRING
* make execute call
If RPC.CALL(ConId, " ", 2, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
* Remapp error codes to match admin codes.
If Error Then
Begin Case
Case Error = UDR.FILEOPENFAILED
Error = EADM.CANTOPEN
Case Error = UDR.RECEXISTS
Error = EADM.UDRHOTRECEXISTS
Case Error = UDR.WRITEFAILED
Error = EADM.CANTWRITE
Case Error = UDR.READFAILED
Error = EADM.CANTREAD
Case 1
Error = EADM.UDRERROR
End Case
End
End Else
Error = STATUS() - 80000
End
End
If Not(Error) Then
Gosub RepGetNextRepSystemKey
Write Params on UvSysFvar, SysKey Else
Error = EADM.CANTWRITE
End
End
ConId = RPC.DISCONNECT(ConId)
End Else
Error = Status() - 80000
End
End
Close UvSysFvar
End Else
Error = EADM.CANTOPEN
End
OutData = SysKey
Return
**********************************************************************
* RepClearRepLog - Clears the Rep Log specified
*
* Input: Control, Rep log Path
* Output:
**********************************************************************
RepClearRepLog:
ReturnCode = 0
Control = Params<1>
InfoFilePath = ""
InfoFileDir = Trim(Params<2>)
InfoFile = Trim(Params<3>)
* Pathname from client
If Control = 1 Then
InfoFilePath = InfoFileDir:OS.SEP:"uvdrlogd.info"
End Else If Control = 2 Then
InfoFilePath = InfoFileDir:OS.SEP:"uvdrrepd.info"
End Else If Control = 3 Then
InfoFilePath = InfoFileDir:OS.SEP:InfoFile
End Else
ReturnCode = EADM.NOFILE
End
OpenSeq InfoFilePath To Flog Locked
ReturnCode = EADM.RECLOCKED
End
Then
* Use writeeof to put an end of file at the begining of the file
* to truncate the rest of the data.
WeofSeq Flog
CloseSeq Flog
End Else
ReturnCode = EADM.NOFILE
End
Error = ReturnCode
Return
**********************************************************************
* RepControl - Controls the replication system
*
* Input: Action required
* Output: Return Code
**********************************************************************
RepControl:
Error = 0
OutData = ""
* Get the control flag from the client
Action = Params<1>
ExLine = ""
Begin Case
Case Action = 1
if OS.TYPE = "MSWIN" then
ExLine = UVHOMEBIN:"uvdrlogd.exe"
ExLine = UVHOMEBIN:"uvbootd ":ExLine
end else
ExLine = UVHOMEBIN:"uvdrlogd &&"
end
Case Action = 2
if OS.TYPE = "MSWIN" then
ExLine = UVHOMEBIN:"uvdrlogd.exe -shutdown"
ExLine = UVHOMEBIN:"uvbootd ":ExLine
end else
ExLine = UVHOMEBIN:"uvdrlogd -shutdown"
end
Case Action = 3
if OS.TYPE = "MSWIN" then
ExLine = UVHOMEBIN:"uvdrrepd.exe"
ExLine = UVHOMEBIN:"uvbootd ":ExLine
end else
ExLine = UVHOMEBIN:"uvdrrepd &&"
end
Case Action = 4
if OS.TYPE = "MSWIN" then
ExLine = UVHOMEBIN:"uvdrrepd.exe -shutdown"
ExLine = UVHOMEBIN:"uvbootd ":ExLine
end else
ExLine = UVHOMEBIN:"uvdrrepd -shutdown"
end
Case 1
Error = EADM.BADCALL
End Case
If Not(Error) Then
Gosub ShellCommand
End
Return
***********************************************************************
* RepDeleteRepSystem - Delete a replication system
*
* Input: System ID
* Output: NONE
***********************************************************************
RepDeleteSystem:
Error = 0
Rec = ""
Key = Params<1>
MachineName = ""
Dim CALL.ARGS(10,2)
Dim RES.ARGS(20,2)
Open "","UV_UDRSYS" To Udrsys.Fvar Then
Read Rec From Udrsys.Fvar, Key Then
If Not(Trim(Rec<4>)) Then
If Trim(Rec<5>) Then
SystemName = Trim(Rec<1>)
* Get the Hostname
ExLine = HOSTNAME
Gosub ShellCommand
MachineName = Trim(Out<1>)
ConId = RPC.CONNECT(SystemName, UDR.SERVICE)
If ConId Then
CALL.ARGS(1,1) = UDR.SRV.REMHOTBACKUPSYS ; * Remove hot backup sys
CALL.ARGS(1,2) = UVRPC.INT
CALL.ARGS(2,1) = MachineName
CALL.ARGS(2,2) = UVRPC.STRING
* make execute call
If RPC.CALL(ConId, " ", 2, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
Error = RES.ARGS(2,1)
* Remapp error codes to match admin codes.
If Error Then
Begin Case
Case Error = UDR.FILEOPENFAILED
Error = EADM.CANTOPEN
Case Error = UDR.RECNOTEXISTS
Error = EADM.UDRHOTRECNOTEXISTS
Case Error = UDR.WRITEFAILED
Error = EADM.CANTWRITE
Case Error = UDR.READFAILED
Error = EADM.CANTREAD
Case Error = UDR.MACHINENOTHOTBACKUP
Error = EADM.MACHINENOTHOTBACKUP
Case 1
Error = EADM.UDRERROR
End Case
End
End Else
Error = STATUS() - 80000
End
ConId = RPC.DISCONNECT(ConId)
End Else
Error = STATUS() - 80000
End
End
If Not(Error) Then
Delete Udrsys.Fvar, Key
End
End Else
Error = EADM.ACTIVESUBS
End
End Else
Error = EADM.CANTREAD
End
Close Udrsys.Fvar
End Else
Error = EADM.CANTOPEN
End
Return
**********************************************************************
* RepExamineRepLog - Returns the Rep Log to examine
*
* Input: Control, Rep Log Path
* Output: Rep Log data
**********************************************************************
RepExamineRepLog:
ReturnCode = 0
NewText = ""
Line = ""
Control = Params<1>
InfoFilePath = ""
InfoFileDir = Trim(Params<2>)
InfoFile = Trim(Params<3>)
If Control = 1 Then
InfoFilePath = InfoFileDir:OS.SEP:"uvdrlogd.info"
End Else If Control = 2 Then
InfoFilePath = InfoFileDir:OS.SEP:"uvdrrepd.info"
End Else If Control = 3 Then
InfoFilePath = InfoFileDir:OS.SEP:InfoFile
End Else
ReturnCode = EADM.NOFILE
End
OpenSeq InfoFilePath To LogFvar Locked
ReturnCode = EADM.RECLOCKED
End
Then
* In case the file is huge, seek to the end and go back 16k
* bytes. Ignore the outcome of this - if it fails, it means
* the file isn't that long, so just read the whole file.
* NB. Can't return more data than this at the moment due to
* RPC package size limitations
Seek LogFvar, -16384, 2 Then
End
Done = False
Loop
ReadSeq Line From LogFvar Else Done = True
Until Done or Status() Do
NewText<-1> = Line
Repeat
CloseSeq LogFvar
OutData = Change(NewText, @FM, CRLF)
End
Else
ReturnCode = EADM.NOFILE
End
Error = ReturnCode
Return
********************************************************************
* RepFailOver -
*
* Input: Sys No
* Output: NONE
********************************************************************
RepFailOver:
SysKey = Params<1>
Error = 0
FileName = ""
AccountName = ""
AccountPath = ""
Id = 0
SubKey = ""
SubType = ""
MDName = ""
FileSubType = ""
SubRecord = ""
Flag = 0
FilePath = ""
OSFileName = ""
VOCFileName = ""
Tmp = ""
EXECUTE "SELECT UV_UDRSUB WITH PUB_SYS = ":SysKey:" AND WITH HOTBACKUP EQ '1'"
Open '', "UV_UDRSUB" To UvSubsFvar Then
Loop
ReadNext SubKey Else SubKey = ""
While SubKey Do
Read SubRecord From UvSubsFvar, SubKey Then
FileName = SubRecord<1>
AccountName = SubRecord<2>
SubType = SubRecord<6,1>
FileSubType = SubRecord<6,2>
DictFileKey = SubRecord<9>
MDName = SubRecord<15>
Readv AccountPath From UVACCOUNT, AccountName, 11 Then
Openpath AccountPath:OS.SEP:"VOC" To UvVocFvar Then
If SubType = "M" Then
VOCFileName = MDName
End Else If SubType = "D" And MDName <> "" Then
*ogo Readv FileSubType From UvSubFvar, DictFileKey, 6 Then
If FileSubType = "M" Then
VOCFileName = MDName
End Else
VOCFileName = FileName
End
* End Else ; * FAILED - Readv DictPubKey
* Error = EADM.BADFILE
* End ; * END - Readv DictPubKey
End Else
VOCFileName = FileName
End
Read VocRecord From UvVocFvar, VOCFileName Then
If SubType EQ "M" Then
Find FileName in VocRecord<7> Setting Fmc, Vmc, Smc Then
Tmp = VocRecord<8,Vmc>
If IsFullPath(Tmp) Then
FilePath = Tmp ; * use multi-part full os file name
End Else
FilePath = AccountPath:OS.SEP:MDName:OS.SEP:Tmp ; * add multi-part os file name
End
End Else
Error = EADM.BADFILE
End ; * END - Find multi-part file name
End Else If SubType = "D" Then
If IsFullPath(VocRecord<3>) Then
FilePath = VocRecord<3>
End Else
FilePath = AccountPath:OS.SEP:VocRecord<3>
End
End Else
If IsFullPath(VocRecord<2>) Then
FilePath = VocRecord<2>
End Else
FilePath = AccountPath:OS.SEP:VocRecord<2>
End
End
End Else ; * FAILED - Read VocRecord
Error = EADM.BADFILE
End ; * END - Read VocRecord
Close UvVocFvar
End Else ; * FAILED - Open account VOC
Error = EADM.BADFILE
End ; * END - Open account VOC
Error = UDRgetheaderinfo(FilePath, Flag, Id)
If Not(Error) Then
If Flag = UDRSUB Then
Error = UDRsetheaderinfo(FilePath, UDRFAILOVER, Id)
If Error Then
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.BADFILETYPE
Case Error = -5
Error = EADM.BADFILEREV
End Case
End
End Else
Error = EADM.UDRNOTINUSE
End
End Else
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.BADFILETYPE
Case Error = -5
Error = EADM.BADFILEREV
End Case
End
End Else
Error = EADM.CANTREADPATH
End
End Else
Error = EADM.CANTREAD
End
Repeat
Open '', "UV_UDRSYS" To UvSysFvar Then
Writev "F" On UvSysFvar, SysKey, 6 Then
Error = UDRsetshmmessage(UDR.REPDELSYS, SysKey, 0, 0, UDRREP)
End Else
Error = EADM.CANTWRITE
End
Close UvSysFvar
End Else
Error = EADM.CANTOPEN
End
Close UvSubsFvar
End Else
Error = EADM.CANTOPEN
End
Return
**********************************************************************
* RepGetMultiLevelFiles - Returns all the multi level and
* distributed files in an account
*
* Input: Account
* Output: List of multi level files and type
**********************************************************************
RepGetMultiLevelFiles:
OutData = ""
AccountName = Params<1>
If IsFullPath(AccountName) Then
AccountPath = AccountName
End Else
* Specific account name
ReadV AccountPath From UVACCOUNT, AccountName, 11 Else
Error = EADM.CANTREADPATH
Return
End
End
**************************************
*** List all the Multi Level files ***
**************************************
* We need a temporary file pointer to be able to do SSELECT
TempRec = "F" : @FM : AccountPath : OS.SEP : "VOC" : @FM : "D_VOC"
Write TempRec On VOC, "BROWSEPTR"
ExLine = \SSELECT BROWSEPTR WITH F1 LIKE "'F'..." AND WITH F4 LIKE "M..."\
ExLine := " AND F2 UNLIKE ...":OS.SEP:"..."
**************************
* OS specific code start *
**************************
* Checking for / on NT as this is still a valid separator in UniVerse files.
If OS.TYPE # "UNIX" Then
ExLine := " AND F2 UNLIKE .../..."
End
************************
* OS specific code end *
************************
Open "BROWSEPTR" To F$Remote Then
Gosub TCLCommand
Done = False
Loop
ReadNext Id From SList Else Done = True
While Id Do
OutData<-1> = Id : @VM : "M"
Repeat
Close F$Remote
End
**************************************
*** List all the distributed files ***
**************************************
OSAccountName = AccountPath
Convert OS.SEP TO @FM IN OSAccountName
**************************
* OS specific code start *
**************************
* Checking for / on NT as this is still a valid separator in UniVerse files.
If OS.TYPE # "UNIX" Then
Convert "/" TO @FM IN OSAccountName
End
************************
* OS specific code end *
************************
OSAccountName = OSAccountName<DCount(OSAccountName,@FM)>
Open "","&PARTFILES&" To UvPartFvar Then
EXECUTE "SELECT &PARTFILES& WITH ACCOUNT = ":OSAccountName: " AND WITH PARTNUM EQ 'Distributed'"
Fin = False
Loop
Readnext Id Then
Read Rec From UvPartFvar, Id Then
DistFile = Rec<1>
Line = DistFile : @VM : "MD"
OutData<-1> = Line
End
End Else Fin = True
Until Fin
Repeat
Close UvPartFvar
End Else
Error = EADM.CANTOPEN
End
Return
**********************************************************************
* RepGetMultiLevelFileParts - Returns all the multi level parts
* for the specified multi level file
*
* Input: Account, Multi Level File name
* Output: List of multi level part files,
* their types and their dicts
* details
**********************************************************************
RepGetMultiLevelFileParts:
OutData = ""
Finish = 0
Ct = 0
File = ""
Dict = ""
OSAccountName = ""
AccountName = Params<1>
MultiLevelFile = Params<2>
FileType = Params<3>
If IsFullPath(AccountName) Then
AccountPath = AccountName
End Else
* Specific account name
ReadV AccountPath From UVACCOUNT, AccountName, 11 Else
Error = EADM.CANTREADPATH
Return
End
End
* We need a temporary file pointer to be able to do SSELECT
TempRec = "F" : @FM : AccountPath : OS.SEP : "VOC" : @FM : "D_VOC"
Write TempRec On VOC, "BROWSEPTR"
If FileType = "M" Then
*******************************************
*** List all the Multi Level part files ***
*******************************************
Open "BROWSEPTR" To F$Remote Then
Read MLRec From F$Remote, MultiLevelFile Then
Ok = True
Finish = DCount(MLRec<7>, @VM)
For Ct = 1 To Finish
File = MLRec<7,Ct>
Dict = MLRec<3>
OutData<-1> = File : @VM : Dict : @VM : FileType
Next Ct
End Else
Error = EADM.CANTREAD
End
Close F$Remote
End
End Else If FileType = "MD" Then
*******************************************
*** List all the distributed part files ***
*******************************************
OSAccountName = AccountPath
Convert OS.SEP TO @FM IN OSAccountName
**************************
* OS specific code start *
**************************
* Checking for / on NT as this is still a valid separator in UniVerse files.
If OS.TYPE # "UNIX" Then
Convert "/" TO @FM IN OSAccountName
End
************************
* OS specific code end *
************************
OSAccountName = OSAccountName<DCount(OSAccountName,@FM)>
Open "","&PARTFILES&" To UvPartFvar Then
EXECUTE "SELECT &PARTFILES& WITH ACCOUNT EQ ":OSAccountName:" AND WITH DISTFILE EQ ":MultiLevelFile:" AND WITH PARTNUM NE 'Distributed'"
Fin = False
Loop
Readnext Id Then
Read Rec From UvPartFvar, Id Then
PartFile = Id
Convert OS.SEP TO @FM IN PartFile
**************************
* OS specific code start *
**************************
* Checking for / on NT as this is still a valid separator in UniVerse files.
If OS.TYPE # "UNIX" Then
Convert "/" TO @FM IN PartFile
End
************************
* OS specific code end *
************************
PartFile = PartFile<DCount(PartFile,@FM)>
Open "BROWSEPTR" To F$Remote Then
Read MLRec From F$Remote, PartFile Then
Dict = MLRec<3>
End Else
Error = EADM.CANTREAD
End
Close F$Remote
End
Line = PartFile : @VM : Dict : @VM : FileType
OutData<-1> = Line
End
End Else Fin = True
Until Fin
Repeat
Close UvPartFvar
End Else
Error = EADM.CANTOPEN
End
End
Return
**********************************************************************
* RepGetPublishedFiles - Returns a list of published files and their
* details
*
* Input: Account
* Output:An array of published filenames and details
**********************************************************************
RepGetPublishedFiles:
Error = 0
OutData = ""
PubRecord = ""
Id = ""
File = ""
Account = Params<1>
AccountName = ""
Type = ""
DictFileId = ""
PntFiles = ""
PntAccounts = ""
PntTypes = ""
PntDictFileId = ""
Open '', "UV_UDRPUB" To UvPubFvar Then
EXECUTE "SELECT UV_UDRPUB WITH ACCOUNT EQ " : Account
Fin = False
Loop
Readnext Id Then
Read PubRecord From UvPubFvar, Id Then
AccountName = PubRecord<2>
File = PubRecord<1>
Type = PubRecord<5,1>
DictFileId = PubRecord<11>
MDName = PubRecord<17>
Line = Id : @vm : File : @vm : Type : @vm : AccountName : @vm : MDName
OutData<-1> = Line
* Add published file links to pub list
PntFiles = PubRecord<12>
PntAccounts = PubRecord<13>
PntTypes = PubRecord<15>
PntDictFileId = PubRecord<16>
If PntFiles NE "" Then
Loop
Remove File From PntFiles Setting Status
Remove AccountName From PntAccounts Setting Status
Remove Type From PntTypes Setting Status
Remove DictFileId From PntDictFileId Setting Status
Line = Id : @VM : File : @VM : Type : @VM : AccountName : @vm : MDName
OutData<-1> = Line
Until Status = 0 Do
Repeat
End
End
End Else Fin = True
Until Fin
Repeat
Close UvPubFvar
End Else
Error = EADM.CANTOPEN
End
Return
**********************************************************************
* RepGetPublishedFileDetails - Returns the details of a published file
*
* Input: Publication Key
* Output:An array of details for the published file
**********************************************************************
RepGetPublishedFileDetails:
Ok = 0
Error = 0
SystemName = ""
SubName = ""
SystemDetails = ""
SubDetails = ""
Rec = ""
SysKey = ""
SubKey = ""
SubAccount = ""
PubKey = Params<1>
Lp = 1
* Open the publications files
Open '', "UV_UDRPUB" To UvPubFvar Then
* Open the systems file
Open '', "UV_UDRSYS" To UvSysFvar Then
Read Rec From UvPubFvar, PubKey Then
* loop reading all the subscription filenames from the pubs file
SubList = Rec<8>
Rec<8> = ""
Loop
Remove SubKey From SubList Setting Ok
If SubKey Then
SubName = Rec<9,Lp>
AccountName = Rec<10,Lp>
SysKey = Rec<7,Lp>
* Get the system record from the systems file
Read SystemDetails From UvSysFvar, SysKey Then
SystemName = SystemDetails<1>
* Build the return data array
Rec<8,-1> = SubKey : @SM : SysKey : @SM : SubName : @SM : AccountName : @SM : SystemName
End Else
Error = EADM.CANTREAD
End
Lp +=1
End
While Ok Do
Repeat
* Load the return data with the output
OutData = Rec
End Else
Error = EADM.CANTREAD
End
Close UvSysFvar
End Else
Error = EADM.CANTOPEN
End
Close UvPubFvar
End Else
Error = EADM.CANTOPEN
End
Return
**********************************************************************
* RepGetRemotePubs - Returns the Remote systems publications
*
* Input: System Id
* Output: Remote Publication List
**********************************************************************
RepGetRemotePubs:
Error = 0
lp =0
Ct = 0
OutData = ""
MachineName = ""
Dim CALL.ARGS(10,2)
Dim RES.ARGS(20,2)
RES.COUNT = 0
* Get system name we are looking for.
SystemName = Params<1>
* Get the Hostname
ExLine = HOSTNAME
Gosub ShellCommand
MachineName = Trim(Out<1>)
* Open Connection and process any error codes that are returned
ConId = RPC.CONNECT(SystemName, UDR.SERVICE)
If ConId Then
* We are ok, start the call
CALL.ARGS(1,1) = UDR.SRV.GETPUBS ; * GetPubs
CALL.ARGS(1,2) = UVRPC.INT
CALL.ARGS(2,1) = MachineName
CALL.ARGS(2,2) = UVRPC.STRING
If SYSTEM(100) Then
CALL.ARGS(3,1) = 1
End Else
CALL.ARGS(3,1) = 0
End
CALL.ARGS(3,2) = UVRPC.INT
* make execute call
If RPC.CALL(ConId, " ", 3, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
OutData = RES.ARGS(3,1)
End Else
Error = STATUS() - 80000
End
* Make call to get publications
If RPC.DISCONNECT(ConId) Else
Error = STATUS() - 80000
End
End Else
* Process Error Message
Error = STATUS() - 80000
End
* Package and return to client
* Close connection
Return
**********************************************************************
* RepGetReplicationConfig - Returns the config information for the
* replication system
*
* Input: None
* Output: Replication config information.
**********************************************************************
RepGetReplicationConfig:
pos =0
Error = 0
line=''
eof = 0
OutData = ""
LogFilePath = ""
* Open the uvreplication config file in the UniVerse home account
config.file = UVHOME : OS.SEP : "uvdr.config"
OpenSeq config.file To FConfig.file Then
* Parse out the replication configuration details.
Loop
ReadSeq line From FConfig.file Else eof = 1
Until eof Do
line=Trim(line)
Begin Case
* Log directory
Case line[1,6]='logdir'
pos = INDEX(line, "=",1)
If pos THEN
OutData<1> = line[pos+1,99]
End
Case line[1,7]='logsize'
* Log size in blocks
pos = INDEX(line, "=",1)
If pos THEN
OutData<2> = line[pos+1,99]
End
Case line[1,10]='logcurrent'
* Current Log directory
pos = INDEX(line, "=",1)
If pos THEN
OutData<3> = line[pos+1,99]
End
Case line[1,7]='logboot'
* Log boot up flag
pos = INDEX(line, "=",1)
If pos THEN
OutData<4> = line[pos+1,99]
End
Case line[1,6]='repdir'
* replication log directory
pos = INDEX(line, "=",1)
If pos THEN
OutData<5> = line[pos+1,99]
End
Case line[1,7]='repboot'
* Replication boot flag
pos = INDEX(line, "=",1)
If pos THEN
OutData<6> = line[pos+1,99]
End
Case line[1,5]='debug'
* Replication debug flag
pos = INDEX(line, "=",1)
If pos THEN
OutData<7> = line[pos+1,99]
End
Case line[1,9]='logoldest'
* oldest log directory to be polled for data
pos = INDEX(line, "=",1)
If pos THEN
OutData<8> = line[pos+1,99]
End
End Case
Repeat
CloseSeq FConfig.file
End
Else
Error = EADM.NOFILE
End
Return
**********************************************************************
* RepGetRepState - Returns the state of the replication daemons
*
* Input: NONE
* Output: Status of the replcation
* Status of subsciption daemons
**********************************************************************
RepGetState:
LogState = 0
Error = 0
OutData = ""
* Get Log State for the replication system
RECIO(LogState, RPINFO$LOG.STATE, RECIO$RPINFO)
OutData = LogState
Error = @SYSTEM.RETURN.CODE
LogState = 0
* Get Log State for the subscription system
RECIO(LogState, RPINFO$REP.STATE, RECIO$RPINFO)
OutData<2> = LogState
If Not(Error) Then
Error = @SYSTEM.RETURN.CODE
End
Return
**********************************************************************
* RepGetSystems - Returns the replication system information
*
*
* Input: A Flag : 1 = List of all publishing systems that provide this
* subscribing system with services.
* 2 = List of all publishing systems that this subscribing
* system provides Hot-Backup services for.
* 3 = List of all subscribing systems that provide this
* publishing system with Hot-Backup services.
* 4 = List of all publishing systems that this subscribing
* system is currently providing Fail Over support for.
* Output: An array with the system information in it.
**********************************************************************
RepGetSystems:
Error = 0
OutData = ""
Id = ""
Rec = ""
Line = ""
SysSched = ""
System = ""
Open "","UV_UDRSYS" To UvSysFvar Then
Begin Case
Case Params = 1
EXECUTE "SELECT UV_UDRSYS WITH STATE_TYPE EQ '' OR STATE_TYPE EQ 'F' AND WITH @ID NE 'HOTBACKUP'"
Case Params = 2
EXECUTE "SELECT UV_UDRSYS WITH HOTBACKUP EQ 1 AND WITH STATE_TYPE EQ ''"
Case Params = 3
EXECUTE "SELECT UV_UDRSYS WITH @ID EQ 'HOTBACKUP'"
Case Params = 4
EXECUTE "SELECT UV_UDRSYS WITH HOTBACKUP EQ 1 AND WITH STATE_TYPE EQ 'F'"
End Case
Fin = False
Loop
Readnext Id Then
Read Rec From UvSysFvar, Id Then
System = Rec<1>
SysSched = Rec<3>
If SysSched = 0 AND Rec<5> = 1 Then
SysSched = "Hot Standby"
End
If Params NE 2 Then
Line = Id : @vm : System : @vm : SysSched
End Else
Line = Id : @vm : System
End
OutData<-1> = Line
End
End Else Fin = True
Until Fin
Repeat
Close UvSysFvar
End Else
Error = EADM.CANTOPEN
End
Return
**********************************************************************
* RepGetSystemNames - Returns the replication system names
*
*
* Input: NONE
* Output: An array with the system names
* in it.
**********************************************************************
RepGetSystemNames:
SystemDetails = ""
Ct = 0
OutData = ""
Key = ""
Open "","UV_UDRSYS" To UvSysFvar Then
EXECUTE "SELECT UV_UDRSYS WITH STATE_TYPE EQ '' AND WITH @ID NE 'HOTBACKUP'"
Loop
Readnext Key Else Null
While Key Do
Read SystemDetails From UvSysFvar, Key Then
Ct+=1
OutData<1,Ct>= Trim(Key)
OutData<2,Ct>= Trim(SystemDetails<1>)
If SystemDetails<5> = 1 Then
OutData<3,Ct> = "1"
End Else
OutData<3,Ct> = "0"
End
End
Repeat
Close UvSubsFvar
End Else
Error = EADM.CANTOPEN
End
Return
**********************************************************************
* RepGetRepSystemDetails - Returns the details of a Rep system
*
* Input: System Key
* Output:An array of details for the rep system
**********************************************************************
RepGetSystemDetails:
SysKey = Params<1>
Error = 0
Rec = ""
OutData = ""
Open '', "UV_UDRSYS" To UvSysFvar Then
Read Rec From UvSysFvar, SysKey Then
OutData = Rec
End Else
Error = EADM.CANTREAD
End
Close UvPubFvar
End Else
Error = EADM.CANTOPEN
End
Return
**********************************************************************
* RepGetSubscriptions - Returns the subscription information
*
*
* Input: Account
* Output: An array with the subscription information
* in it.
**********************************************************************
RepGetSubscriptions:
Error = 0
Id = ""
OutData = ""
SystemName = ""
Line = ""
SubRecord = ""
File = ""
Account = Params<1>
AccountName = ""
Type = ""
MDName = ""
PntFiles = ""
PntAccounts = ""
PntTypes = ""
* Open the subscription file
Open '', "UV_UDRSUB" To UvSubsFvar Then
* Open the Systems file
Open "","UV_UDRSYS" To UvSysFvar Then
EXECUTE "SELECT UV_UDRSUB WITH ACCOUNT EQ " : Account
Fin = False
Loop
Readnext Id Then
Read SubRecord From UvSubsFvar, Id Then
File = SubRecord<1>
AccountName = SubRecord<2>
Type = SubRecord<6,1>
MDName = SubRecord<15>
Readv SystemName From UvSysFvar, SubRecord<5>, 1 Else
SystemName = "Invalid System"
End
* Build the return line
Line = Id : @vm : File : @vm : Type : @vm : AccountName : @vm : MDName : @vm : SystemName
OutData<-1> = Line
* Add subscribed file links to sub list
PntFiles = SubRecord<10>
PntAccounts = SubRecord<11>
PntTypes = SubRecord<13>
If PntFiles NE "" Then
Loop
Remove File From PntFiles Setting Status
Remove AccountName From PntAccounts Setting Status
Remove Type From PntTypes Setting Status
Line = Id : @VM : File : @VM : Type : @VM : AccountName : @vm : MDName : @VM : SystemName
OutData<-1> = Line
Until Status = 0 Do
Repeat
End
End
End Else
Fin = True
End
Until Fin
Repeat
Close UvSysFvar
End Else
Error = EADM.CANTOPEN
End
Close UvSubsFvar
End Else
Error = EADM.CANTOPEN
End
Return
**********************************************************************
* RepGetSubscriptionDetails - Returns the details of a subscription file
*
* Input: Subscription Key
* Output:An array of details for the subscription file
**********************************************************************
RepGetSubscriptionDetails:
Id = Params<1>
SystemName = ""
Rec = ""
OutData = ""
Open '', "UV_UDRSUB" To UvSubsFvar Then
Open "","UV_UDRSYS" To UvSysFvar Then
Read Rec From UvSubsFvar, Id Then
Readv SystemName From UvSysFvar, Rec<5>, 1 Else
SystemName = "Invalid System"
End
* Rec<5> = SystemName
OutData = Rec : @FM : SystemName
End
Close UvSysFvar
End Else
Error = EADM.CANTOPEN
End
Close UvSubsFvar
End Else
Error = EADM.CANTOPEN
End
Return
******************************************************************************
* RepGetUVFiles - Like a normal Browse, but instead of browsing the
* OS file system, it browses the UniVerse account/file
* system.
*
* Input: Account name to browse
* File types to include
* Output: List of files
******************************************************************************
RepGetUVFiles:
Done = False
Status = 0
FileInfo = ""
DictName = ""
AccountName = Params<1>
AccountPath = ""
VOCRecord = ""
* prepare list of exceptions
* then before including files in the list, check against exceptions
Gosub RepBuildUVFileExceptionList
* Add all standard File pointers to the list minus Multi-level files
Write "Q" : @FM : AccountName : @FM : "VOC" : @FM : "D_VOC" On VOC, "BROWSEPTR"
ExLine = "SSELECT BROWSEPTR WITH F1 LIKE F... AND F4 UNLIKE M..."
Gosub TCLCommand
Readv AccountPath From UVACCOUNT, AccountName, 11 Then
Openpath AccountPath:OS.SEP:"VOC" To UvVocFvar Then
Loop
ReadNext Id From SList Else Done = True
Until Done Do
Find Id IN ExceptionList Setting Fmc
Else
Read VOCRecord From UvVocFvar, Id Then
DictName = VOCRecord<3>
FileInfo<1> = Id : @VM : DictName : @VM : "F"
OutData<-1> = FileInfo
End ; * END - Readv VOCRecord
End
Repeat
Close UvVocFvar
End Else ; * FAILED - Open account VOC
Error = EADM.BADFILE
End ; * END - Open account VOC
End Else ; * FAILED - Readv AccountPath
Error = EADM.BADFILE
End ; * END - Readv AccountPath
* add all q-pointers to the file list
Done = False
ExLine = "SSELECT BROWSEPTR WITH F1 LIKE Q..."
Gosub TCLCommand
Loop
ReadNext Id From SList Else Done = True
Until Done Do
If Id <> "BROWSEPTR" Then
FileInfo<1> = Id : @VM : "" : @VM : "Q"
OutData<-1> = FileInfo
End
Repeat
Delete VOC, "BROWSEPTR"
Return
**********************************************************************
* RepPublishFile - Publishes a file for replication
*
* Input: Publication Details
* Output: Publication Key
**********************************************************************
RepPublishFile:
Error = 0
FileName = Params<1>
Account = Params<2>
Description = Params<3>
PubType = Params<4> ; * F=regular, D=dictionary, M=multi-part, MD=distributed, Q=Q-pointers
AccessList = Params<5>
FileKeyForDictPub = Params<6>
MDName = Params<7>
DictName = Params<8>
ResultPubKey = ""
MFileName = ""
MPartName = ""
AccountPath = ""
VOCRecord = ""
Readv AccountPath From UVACCOUNT, Account, 11 Then
* process the type of publication requested
If Not(Error) Then
If PubType = "F" Or PubType = "MD" Then ; * publish standard UniVerse file
Gosub RepPublishFileFType
End Else If PubType = "D" Then ; * publish UniVerse file dictionary
Gosub RepPublishFileDType
End Else If PubType = "Q" Then ; * publish UniVerse Q-pointer
Gosub RepPublishFileQType
End Else If PubType = "M" Then ; * publish UniVerse Multi-Level file
MFileName = MDName
MPartName = FileName
Gosub RepPublishFileMType
End Else ; * No valid PubType provided
Error = EADM.BADFILE
End ; * Finished publishing file
End
End Else ; * FAILED - Readv AccountPath
Error = EADM.BADFILE
End ; * END - Readv AccountPath
OutData = ResultingPubKey
Return
********************************************************************
* RepRemoveRemoteSub - Remove a subscription on a remote subscriber
* of a publication on this system
*
* Input: Key to published file record in UV_UDRPUB
* Output: Any error message generated
********************************************************************
RepRemoveRemoteSub:
Error = 0
PubRecord = ""
Pos = 0
PubKey = Params<1>
SubKey = Params<2>
SysKey = Params<3>
Open '', "UV_UDRPUB" To UvPubFvar Then
Read PubRecord From UvPubFvar, PubKey Then
Find SubKey In PubRecord<8> Setting Pos Then
Del PubRecord<10,Pos> ; * these are deleted in reverse order because array shrinks with delete
Del PubRecord<9,Pos>
Del PubRecord<8,Pos>
Del PubRecord<7,Pos>
Error = UDRsetshmmessage(UDR.LOGDELREMSUB, PubKey, SysKey, SubKey, UDRLOG)
Write PubRecord To UvPubFvar, PubKey Else
Error = EADM.CANTWRITE
End
End Else
Error = EADM.BADFILE
End
End Else
Error = EADM.CANTREAD
End
End Else
Error = EADM.CANTOPEN
End
Return
**********************************************************************
* RepRepairFile - Repairs the replication configuration for a file.
*
* ogo - we still need to add support for many broken states
* Supports - Clearing the replication id and flag from a file marked
* for replication.(Does not fix the replication config)
* Does not Support - Anything other than the above.
* Input: File Rep ID
* File Dict Rep ID
* Account
* FileName
* Rep FileType
* Multi level/Distributed Name
* Output: None
**********************************************************************
RepRepairFile:
Error = 0
FileID = Params<1>
DictID = Params<2>
Account = Params<3>
FileName = Params<4>
FileType = Params<5> ; * F=regular, M=multi-part, MD=distributed, Q=Q-pointers, D=dictionary
MDName = Params<6>
AccountPath = ""
FilePath = ""
VOCFileName = ""
VOCRecord = ""
OldFileType = ""
Tmp = ""
RepRepairFile.GetFilePath:
* figure out filepath for the file in question
If FileType = "F" Or FileType = "M" Or FileType = "MD" Or FileType = "D" Then
Readv AccountPath From UVACCOUNT, Account, 11 Then
Openpath AccountPath:OS.SEP:"VOC" To UvVocFvar Then
If FileType = "M" Then
VOCFileName = MDName
End Else If FileType = "D" And OldFileType = "M" Then
VOCFileName = MDName
End Else
VOCFileName = FileName
End
Read VocRecord From UvVocFvar, VOCFileName Then
If FileType EQ "M" Then
Find FileName in VocRecord<7> Setting Fmc, Vmc, Smc Then
Tmp = VocRecord<8,Vmc>
If IsFullPath(Tmp) Then
FilePath = Tmp ; * use multi-part full os file name
End Else
FilePath = AccountPath:OS.SEP:MDName:OS.SEP:Tmp ; * add multi-part os file name
End
End Else
Error = EADM.BADFILE
End ; * END - Find multi-part file name
End Else If FileType = "D" Then
If IsFullPath(VocRecord<3>) Then
FilePath = VocRecord<3>
End Else
FilePath = AccountPath:OS.SEP:VocRecord<3>
End
End Else
If IsFullPath(VocRecord<2>) Then
FilePath = VocRecord<2>
End Else
FilePath = AccountPath:OS.SEP:VocRecord<2>
End
End
End Else ; * FAILED - Read VocRecord
Error = EADM.BADFILE
End ; * END - Read VocRecord
Close UvVocFvar
End Else ; * FAILED - Open account VOC
Error = EADM.BADFILE
End ; * END - Open account VOC
End Else ; * FAILED - read account path
Error = EADM.CANTREAD
End ; * END - read account path
End
Error = UDRsetheaderinfo(FilePath, UDRNONE, 0)
If Error Then
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.BADFILETYPE
Case Error = -5
Error = EADM.BADFILEREV
End Case
Goto Exit.RepRepairFile
End
* now repair the files dictionary in case that has problems as well
If FileType <> "D" And Error = 0 Then
OldFileType = FileType
FileType = "D"
Goto RepRepairFile.GetFilePath
End
Exit.RepRepairFile:
OutData = ""
Return
********************************************************************
* RepResumeLogManager - Try ro make the log manager ressume after a FULL
*
* Input: None
* Output: Any error message generated
********************************************************************
RepResumeLogManager:
Error = 0
* Send the resume message to the log manager
Flag = 0
Error = UDRsetshmmessage(UDR.LOGRESUME, Flag, 0, 0, UDRLOG)
Return
**********************************************************************
* RepSaveReplicationConfig - Saves the replication config
* information
*
* Input: Replication config information
* Output: None
**********************************************************************
RepSaveReplicationConfig:
rec=""
line = ""
line.no = 0
eof = 0
Error = 0
found.replogdir = 0
found.replogsize = 0
found.repcurrentlog = 0
found.repoldestlog = 0
found.repboot = 0
found.sublogdir = 0
found.subboot = 0
found.repsubdebug = 0
* Load client values.
switch = Params<1>
replogdir = Params<2>
replogsize = Params<3>
repcurrentlog = Params<4>
repboot = Params<5>
sublogdir = Params<6>
subboot = Params<7>
repsubdebug = Params<8>
repoldestlog = Params<9>
* Open the replication config file.
config.file = UVHOME : OS.SEP : "uvdr.config"
OpenSeq config.file To FConfig.file Then
* Parse the current values from the file and replace with the new values
Loop
ReadSeq line From FConfig.file else eof = 1
Until eof Do
* If we are doing the log manager settings.
If switch = "REP" Then
Begin Case
Case line[1,6]='logdir'
line="logdir=":replogdir
found.replogdir = 1
Case line[1,7]='logsize'
line="logsize=":replogsize
found.replogsize = 1
Case line[1,10]='logcurrent'
line="logcurrent=":repcurrentlog
found.repcurrentlog = 1
Case line[1,9]='logoldest'
line="logoldest=":repoldestlog
found.repoldestlog = 1
Case line[1,7]='logboot'
line="logboot=":repboot
found.repboot = 1
Case line[1,5]='debug'
line="debug=":repsubdebug
found.repsubdebug = 1
Case 1
line=line
End Case
End Else
* Replication settings
Begin Case
Case line[1,6]='repdir'
line="repdir=":sublogdir
found.sublogdir = 1
Case line[1,7]='repboot'
line="repboot=":subboot
found.subboot = 1
Case line[1,5]='debug'
line="debug=":repsubdebug
found.repsubdebug = 1
Case 1
line=line
End Case
End
line.no += 1
rec< line.no > = line
repeat
CloseSeq FConfig.file
* If the entry was not found add it.
If switch = "REP" Then
If found.replogdir = 0 Then
line.no +=1
rec<line.no>="logdir=":replogdir
End
If found.replogsize = 0 Then
line.no += 1
rec<line.no> = "logsize=":replogsize
End
If found.repcurrentlog = 0 Then
line.no += 1
rec<line.no> = "logcurrent=":repcurrentlog
End
If found.repoldestlog = 0 Then
line.no += 1
rec<line.no> = "logoldest=":repoldestlog
End
If found.repboot = 0 Then
line.no += 1
rec<line.no> = "logboot=":repboot
End
If found.repsubdebug = 0 Then
line.no += 1
rec<line.no> = "debug=":repsubdebug
End
End Else
If found.sublogdir = 0 Then
line.no += 1
rec<line.no> = "repdir=":sublogdir
End
If found.subboot = 0 Then
line.no += 1
rec<line.no> = "repboot=":subboot
End
If found.repsubdebug = 0 Then
line.no += 1
rec<line.no> = "debug=":repsubdebug
End
End
OpenSeq config.file TO FConfig.file Else
Error = EADM.NOFILE
End
FOR i = 1 TO line.no
WriteSeq rec< i > TO FConfig.file else
Error = EADM.CANTWRITE
End
Next i
WeofSeq FConfig.file
End
Else
* We could not open the file, we assume that it is
* not there and create it
Create FConfig.file Then
rec=""
If switch = "REP" Then
rec<1>="logdir=":replogdir
rec<2>="logsize=":replogsize
rec<3>="logcurrent=":repcurrentlog
rec<4>="logoldest=":repoldestlog
rec<5>="logboot=":repboot
rec<6>="repdir="
rec<7>="repboot="
rec<8>="debug=":repsubdebug
End Else
rec<1>="logdir="
rec<2>="logsize="
rec<3>="logcurrent="
rec<4>="logoldest="
rec<5>="logboot="
rec<6>="repdir=":sublogdir
rec<7>="repboot=":subboot
rec<8>="debug=":repsubdebug
End
Convert @FM To Char(10) in rec
WriteSeq rec To FConfig.file Else
Error =EADM.CANTWRITE
End
CloseSeq FConfig.file
End Else
Error = EADM.CANTCREATE
End
End
Return
**********************************************************************
* RepSubscribeFile - Subscribes a file for replication
*
* Input: Subscription Details
* Output: Subscription Key
**********************************************************************
RepSubscribeFile:
Error = 0
Dim CALL.ARGS(10,2)
Dim RES.ARGS(20,2)
RES.COUNT = 0
FileName = Params<1>
Account = Params<2>
Description = Params<3>
SubType = Params<4> ; * F=regular, D=dictionary, M=multi-part, MD=distributed, Q=Q-pointers
HotStandby = Params<5>
MDName = Params<6>
SubIDForDict = Params<7>
DictName = Params<8>
SysKey = Params<10>
PubKey = Params<11>
PubFileAndAccount = Params<12>
VOCRecord = ""
SubRecord = ""
AccountPath = ""
FilePath = ""
SystemName = ""
OSFileName = ""
MPartNames = ""
MOSPartNames = ""
QAccountName = ""
QAccountPath = ""
QFileName = ""
DTypeFileName = ""
DictSubKey = ""
Flag = 0
Id = 0
LogState = 0
SubKey = ""
QSubKey = ""
SysArray = ""
ConId = 0
Tmp = ""
Readv AccountPath From UVACCOUNT, Account, 11 Then
ExLine = HOSTNAME
Gosub ShellCommand
MachineName = Trim(Out<1>)
* Check to see if the subscription is a hot standby one if
* it is, check to see if there is already a hot standby for the
* publication file specified.
If HotStandby Then
EXECUTE "SELECT UV_UDRSUB WITH PUB_KEY = ":PubKey:" AND WITH HOTBACKUP NE '' AND WITH PUB_SYS = ":SysKey
IF @SELECTED Then
Error = EADM.PUBHASHOTBACKUP
Goto Exit.Subscribefile
End
End
If SubType = "D" Then
* determine if this is a dictionary for a Multi-level file or regular file
Open '', "UV_UDRSUB" To UvSubFvar Then
Readv DTypeSubType From UvSubFvar, SubIDForDict, 6 Then
If DTypeSubType = "M" Then
DTypeFileName = MDName
End Else
DTypeFileName = FileName
End
End Else ; * FAILED - Readv DictPubKey
Error = EADM.BADFILE
End ; * END - Readv DictPubKey
Close UvSubFvar
End Else
Error = EADM.CANTOPEN
End
End
* figure out filepath for the file in question
Openpath AccountPath:OS.SEP:"VOC" To UvVocFvar Then
If SubType = "F" Or SubType = "MD" Then ; * Get filepath for normal File type
Readv OSFileName From UvVocFvar, FileName, 2 Then
If IsFullPath(OSFileName) Then
FilePath = OSFileName
End Else
FilePath = AccountPath:OS.SEP:OSFileName
End
End Else ; * FAILED - Readv OSFileName
Error = EADM.BADFILE
End ; * END - Readv OSFileName
End Else If SubType = "D" Then ; * Get filepath for dictionary
Readv OSFileName From UvVocFvar, DTypeFileName, 3 Then
If IsFullPath(OSFileName) Then
FilePath = OSFileName
End Else
FilePath = AccountPath:OS.SEP:OSFileName
End
End Else ; * FAILED - Readv OSFileName
Error = EADM.BADFILE
End ; * END - Readv OSFileName
End Else If SubType = "M" Then ; * Get filepath for Multi-level File type
Readv MPartNames From UvVocFvar, MDName, 7 Then
Find FileName in MPartNames Setting Fmc, Vmc, Smc Then
Readv MOSPartNames From UvVocFvar, MDName, 8 Then
Tmp = MOSPartNames<Fmc,Vmc>
If IsFullPath(Tmp) Then
FilePath = Tmp ; * use multi-part full os file name
End Else
FilePath = AccountPath:OS.SEP:MDName:OS.SEP:Tmp ; * add multi-part os file name
End
End Else ; * FAILED - Readv MOSPartNames
Error = EADM.BADFILE
End
End Else
Error = EADM.BADFILE
End ; * END - Find multi-part file name
End Else ; * FAILED - Readv MPartNames
Error = EADM.BADFILE
End ; * END - Readv MPartNames
End Else If SubType = "Q" Then ; * Get filepath for Q-pointer File type
Readv QAccountName From UvVocFvar, FileName, 2 Then
Readv QFileName From UvVocFvar, FileName, 3 Then
Readv QAccountPath From UVACCOUNT, QAccountName, 11 Then
Openpath QAccountPath:OS.SEP:"VOC" To UvVocFvar2 Then
Readv OSFileName From UvVocFvar2, QFileName, 2 Then
If IsFullPath(OSFileName) Then
FilePath = OSFileName
End Else
FilePath = QAccountPath:OS.SEP:OSFileName
End
End Else ; * FAILED - Readv OSFileName
Error = EADM.BADFILE
End ; * END - Readv OSFileName
Close UvVocFvar2
End Else ; * FAILED - Open Q-pointer account VOC
Error = EADM.BADFILE
End ; * END - Open Q-pointer account VOC
End Else ; * FAILED - Readv QAccountPath
Error = EADM.BADFILE
End ; * END - Readv QAccountPath
End Else ; * FAILED - Readv QFileName
Error = EADM.BADFILE
End ; * END - Readv QFileName
End Else ; * FAILED - Readv QAccountName
Error = EADM.BADFILE
End ; * END - Readv QAccountName
End Else ; * No valid file type specified
Error = EADM.BADFILETYPE
End
Close UvVocFvar
End Else ; * FAILED - Open account VOC
Error = EADM.BADFILE
End ; * END - Open account VOC
If Error NE 0 Then
Goto Exit.Subscribefile
End
* check if file already subscribed
Error = UDRgetheaderinfo(FilePath, Flag, Id)
If Not(Error) Then
If Flag = UDRNONE Then
Gosub RepGetNextSubscriptionKey
If Not(Error) Then
Open '', "UV_UDRSUB" To UvSubFvar Then
If SubType = "Q" Then
SubRecord<1> = QFileName
SubRecord<2> = QAccountName
SubRecord<3> = "Subscribed via a Q-Pointer"
SubRecord<6> = "F"
End Else If SubType = "D" Then
SubRecord<1> = FileName
SubRecord<2> = Account
SubRecord<3> = Description
SubRecord<6> = SubType : @VM : DTypeSubType
End Else ; * default case used for standard file types
SubRecord<1> = FileName
SubRecord<2> = Account
SubRecord<3> = Description
SubRecord<6> = SubType
End
SubRecord<4> = PubKey
SubRecord<5> = SysKey
SubRecord<7> = HotStandby
SubRecord<8> = PubFileAndAccount
SubRecord<9> = SubIDForDict
SubRecord<15> = MDName
SubRecord<16> = DictName
Write SubRecord To UvSubFvar, SubKey Then
If SubType = "D" Then
* now we need to set the parent file flag.
Readv DictSubKey From UvSubFvar, SubIDForDict, 9 Then
If DictSubKey <> 0 Then
Error = EADM.UDRINUSE
End
Writev SubKey To UvSubFvar, SubIDForDict, 9 Else
Error = EADM.CANTWRITE
End
End Else ; * FAILED - Readv DictSubKey
Error = EADM.BADFILE
End ; * END - Readv DictSubKey
End
If SubType = "MD" Then
Gosub RepDistFileAdminSet
End
If Not(Error) Then
Error = UDRsetheaderinfo(FilePath, UDRSUB, SubKey)
End
If Not(Error) Then
Open '', "UV_UDRSYS" To UvSysFvar Then
Read SysArray From UvSysFvar, SysKey Then
SysArray<4,-1> = SubKey
SystemName = SysArray<1>
Write SysArray To UvSysFvar, SysKey Else
Error = EADM.CANTWRITE
End
If DCount(SysArray, @VM) = 1 Then
* First Subscription signal schedular to add
* Get Log State for the subscription system
RECIO(LogState, RPINFO$REP.STATE, RECIO$RPINFO)
If LogState Then
Error = UDRsetshmmessage(UDR.REPADDSYS, SysKey, 0, 0, UDRREP)
If Error Then
Error = EADM.BADCALL
End
End
End
End Else
Error = EADM.CANTREAD
End
Close UvSysFvar
End Else
Error = EADM.CANTOPEN
End
ConId = RPC.CONNECT(SystemName, UDR.SERVICE)
If ConId Then
* Update the remote with the subscription details
* We are ok, start the call
CALL.ARGS(1,1) = UDR.SRV.SETSUB ; * Register subscription
CALL.ARGS(1,2) = UVRPC.INT
CALL.ARGS(2,1) = PubKey
CALL.ARGS(2,2) = UVRPC.STRING
CALL.ARGS(3,1) = MachineName
CALL.ARGS(3,2) = UVRPC.STRING
CALL.ARGS(4,1) = SubKey
CALL.ARGS(4,2) = UVRPC.STRING
If SubType = "Q" Then
CALL.ARGS(5,1) = QFileName
CALL.ARGS(5,2) = UVRPC.STRING
CALL.ARGS(6,1) = QAccountName
CALL.ARGS(6,2) = UVRPC.STRING
End Else ; * default case used for standard file types
CALL.ARGS(5,1) = FileName
CALL.ARGS(5,2) = UVRPC.STRING
CALL.ARGS(6,1) = Account
CALL.ARGS(6,2) = UVRPC.STRING
End
* make execute call
If RPC.CALL(ConId, " ", 6, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
OutData = RES.ARGS(3,1)
End Else
Error = STATUS() - 80000
End
ConId = RPC.DISCONNECT(ConId)
End Else
Error = Status() - 80000
End
End Else
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.UDRINVALIDFILE
Case Error = -5
Error = EADM.BADFILEREV
End Case
End
End Else
Error = EADM.CANTWRITE
End
Close UvSubFvar
End Else
Error = EADM.CANTOPEN
End
End
End
If Flag NE UDRPUB AND SubType = "Q" Then
Open '', "UV_UDRSUB" To UvSubFvar Then
If Flag = UDRNONE Then
QSubKey = SubKey
End Else If Flag = UDRSUB Then
QSubKey = Id
End
Readu SubRecord From UvSubFvar, QSubKey Then
SubRecord<10,-1> = FileName
SubRecord<11,-1> = Account
SubRecord<12,-1> = Description
SubRecord<13,-1> = SubType
SubRecord<14,-1> = "0"
Write SubRecord To UvSubFvar, QSubKey Else
Error = EADM.CANTWRITE
End
End Else
Error = EADM.CANTREAD
End
Close UvSubFvar
End Else
Error = EADM.CANTOPEN
End
End
If (Flag NE UDRNONE AND SubType NE "Q") OR Flag = UDRPUB Then
Error = EADM.UDRINUSE
End
End Else
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.UDRINVALIDFILE
Case Error = -5
Error = EADM.BADFILEREV
End Case
End
End Else
Error = EADM.BADFILE
End
Exit.Subscribefile:
If SubType = "Q" Then
OutData = QSubKey
End Else
OutData = SubKey
End
Return
***********************************************************************
* RepUnPublish - Unpublishs a replication publication
*
* Input: Params<1> = Publication ID
* Params<2> = File VOC Name
* Params<3> = Account Name
* Output: NONE
***********************************************************************
RepUnPublish:
Error = 0
LogState = 0
Key = Params<1>
File = Params<2>
Account = Params<3>
AccountPath = ""
FilePath = ""
FileName = ""
AccountName = ""
Id = 0
PubRecord = ""
Tmp = ""
LogState = 0
PubType = ""
DictFileKey = 0
EmptyKey = "0"
MDName = ""
VOCReadName = ""
Open "","UV_UDRPUB" To UvPubFvar Then
Readu PubRecord From UvPubFvar, Key Then
FileName = PubRecord<1>
AccountName = PubRecord<2>
PubType = PubRecord<5,1>
DictFileKey = PubRecord<11>
MDName = PubRecord<17>
If File EQ FileName AND Account EQ AccountName Then ; * this is a published file
Readv AccountPath From UVACCOUNT, AccountName, 11 Then
Openpath AccountPath:OS.SEP:"VOC" To UvVocFvar Then
If PubType EQ "M" Then
VOCReadName = MDName
End Else If PubType EQ "D" Then
Readv FilePubType From UvPubFvar, DictFileKey, 5 Then
If FilePubType = "M" Then
VOCReadName = MDName
End Else
VOCReadName = File
End
End Else ; * FAILED - Readv DictPubKey
Error = EADM.BADFILE
End ; * END - Readv DictPubKey
End Else
VOCReadName = File
End
Read VocRecord From UvVocFvar, VOCReadName Then
If PubType EQ "M" Then
Find File in VocRecord<7> Setting Fmc, Vmc, Smc Then
Tmp = VocRecord<8,Vmc>
If IsFullPath(Tmp) Then
FilePath = Tmp ; * use multi-part full os file name
End Else
FilePath = AccountPath:OS.SEP:MDName:OS.SEP:Tmp ; * add multi-part os file name
End
End Else
Error = EADM.BADFILE
End ; * END - Find multi-part file name
End Else If PubType EQ "D" Then
If IsFullPath(VocRecord<3>) Then
FilePath = VocRecord<3>
End Else
FilePath = AccountPath:OS.SEP:VocRecord<3>
End
End Else
If IsFullPath(VocRecord<2>) Then
FilePath = VocRecord<2>
End Else
FilePath = AccountPath:OS.SEP:VocRecord<2>
End
End
If Not(Error) Then
Error = UDRgetheaderinfo(FilePath, Flag, Id)
End
If Not(Error) Then
If Flag = UDRPUB Then
If Key = Id Then
Error = UDRsetheaderinfo(FilePath, UDRNONE, 0)
If Error Then
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.BADFILETYPE
Case Error = -5
Error = EADM.BADFILEREV
End Case
End
Delete UvPubFvar, Key Else
Error = EADM.CANTWRITE
End
If PubType = "D" Then
* remove reference from file publication for dictionary unpublish
Readvu Tmp From UvPubFvar, DictFileKey, 11 Else
Error = EADM.CANTREAD
End
Writev EmptyKey On UvPubFvar, DictFileKey, 11 Then
End Else
Error = EADM.CANTWRITE
End
End
If PubType = "MD" Then
Gosub RepDistFileAdminClear
End
* Tell the log manager we are out of here
* Get Log State for the subscription system
RECIO(LogState, RPINFO$LOG.STATE, RECIO$RPINFO)
* Test to see if the daemon is running
If LogState Then
Error = UDRsetshmmessage(UDR.LOGDELPUB, Key, 0, 0, UDRLOG)
If Error Then
Error = EADM.BADFUNCCALL
End
End
End Else
Error = EADM.UDRINVALIDFILE
End
End Else
Error = EADM.UDRNOTINUSE
End
End Else
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.BADFILETYPE
Case Error = -5
Error = EADM.BADFILEREV
End Case
End
End Else ; * FAILED - Read VocRecord
Error = EADM.BADFILE
End ; * END - Read VocRecord
Close UvVocFvar
End Else ; * FAILED - Open account VOC
Error = EADM.BADFILE
End ; * END - Open account VOC
End Else ; * FAILED - read account path
Error = EADM.CANTREAD
End ; * END - read account path
End Else ; * This is a file pointer not a published file
Find File In PubRecord<12> Setting Pos Then
If PubRecord<13,Pos> EQ Account Then
Del PubRecord<16, Pos> ; * these are deleted in reverse order because array shrinks with delete
Del PubRecord<15, Pos>
Del PubRecord<14, Pos>
Del PubRecord<13, Pos>
Del PubRecord<12, Pos>
Write PubRecord To UvPubFvar, Key Else
Error = EADM.CANTWRITE
End
End Else
Error = EADM.BADFILE
End
End Else
Error = EADM.BADFILE
End
End
End Else
Error = EADM.CANTREAD
End
Close UvPubFvar
End Else
Error = EADM.CANTOPEN
End
Return
***********************************************************************
* RepUnSubscribe - Unsubscribes a replication subscription
*
* Input: Subscription ID
* File Name
* Account Name
* Output: NONE
***********************************************************************
RepUnSubscribe:
Dim CALL.ARGS(10,2)
Dim RES.ARGS(20,2)
RES.COUNT = 0
ConId = 0
MachineName = ""
Error = 0
SubKey = Params<1>
File = Params<2>
Account = Params<3>
FileName = ""
AccountName = ""
AccountPath = ""
FilePath = ""
PubKey = ""
SystemName = ""
SysRecord = ""
Pos = 0
SubRecord = ""
SysKey = ""
VOCFileName = ""
MDName = ""
UnSubType = ""
SubType = ""
FileSubType = ""
DictFileKey = 0
EmptyKey = "0"
Flag = 0
Id = 0
LogState = 0
Tmp = ""
* get our local machine name
ExLine = HOSTNAME
Gosub ShellCommand
MachineName = Trim(Out<1>)
* get the details of the subscription we are to remove
Open "","UV_UDRSUB" To UvSubFvar Then
Read SubRecord From UvSubFvar, SubKey Then
FileName = SubRecord<1>
AccountName = SubRecord<2>
PubKey = SubRecord<4>
SysKey = SubRecord<5>
SubType = SubRecord<6,1>
DictFileKey = SubRecord<9>
MDName = SubRecord<15>
End Else
Error = EADM.CANTREAD
Goto Exit.RepUnSubscribe
End
End Else
Error = EADM.CANTOPEN
Goto Exit.RepUnSubscribe
End
* figure out filepath for the file in question
If SubType = "F" Or SubType = "M" Or SubType = "MD" Or SubType = "D" Then ; * this is a subscribed file
UnSubType = "F"
Readv AccountPath From UVACCOUNT, AccountName, 11 Then
Openpath AccountPath:OS.SEP:"VOC" To UvVocFvar Then
If SubType = "M" Then
VOCFileName = MDName
End Else If SubType = "D" And MDName <> "" Then
Readv FileSubType From UvSubFvar, DictFileKey, 6 Then
If FileSubType = "M" Then
VOCFileName = MDName
End Else
VOCFileName = FileName
End
End Else ; * FAILED - Readv DictPubKey
Error = EADM.BADFILE
End ; * END - Readv DictPubKey
End Else
VOCFileName = FileName
End
Read VocRecord From UvVocFvar, VOCFileName Then
If SubType EQ "M" Then
Find FileName in VocRecord<7> Setting Fmc, Vmc, Smc Then
Tmp = VocRecord<8,Vmc>
If IsFullPath(Tmp) Then
FilePath = Tmp ; * use multi-part full os file name
End Else
FilePath = AccountPath:OS.SEP:MDName:OS.SEP:Tmp ; * add multi-part os file name
End
End Else
Error = EADM.BADFILE
End ; * END - Find multi-part file name
End Else If SubType = "D" Then
If IsFullPath(VocRecord<3>) Then
FilePath = VocRecord<3>
End Else
FilePath = AccountPath:OS.SEP:VocRecord<3>
End
End Else
If IsFullPath(VocRecord<2>) Then
FilePath = VocRecord<2>
End Else
FilePath = AccountPath:OS.SEP:VocRecord<2>
End
End
End Else ; * FAILED - Read VocRecord
Error = EADM.BADFILE
End ; * END - Read VocRecord
Close UvVocFvar
End Else ; * FAILED - Open account VOC
Error = EADM.BADFILE
End ; * END - Open account VOC
End Else ; * FAILED - read account path
Error = EADM.CANTREAD
End ; * END - read account path
End Else ; * This is a file pointer not a published file
UnSubType = "Q"
End
If UnSubType = "F" Then
Error = UDRgetheaderinfo(FilePath, Flag, Id)
If Error Then
If Error Then
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.BADFILETYPE
Case Error = -5
Error = EADM.BADFILEREV
End Case
End
Goto Exit.RepUnSubscribe
End
If Flag = UDRSUB Else
Error = EADM.UDRNOTINUSE
Goto Exit.RepUnSubscribe
End
End
If UnSubType = "F" AND SubKey = Id Then
Error = UDRsetheaderinfo(FilePath, UDRNONE, 0)
If Error Then
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.BADFILETYPE
Case Error = -5
Error = EADM.BADFILEREV
End Case
Goto Exit.RepUnSubscribe
End
Delete UvSubFvar, SubKey Else
Error = EADM.CANTWRITE
Goto Exit.RepUnSubscribe
End
If SubType = "D" Then
* remove reference from file subscription for dictionary unsubscribe
Readvu Tmp From UvSubFvar, DictFileKey, 9 Else
Error = EADM.CANTREAD
Goto Exit.RepUnSubscribe
End
Writev EmptyKey On UvSubFvar, DictFileKey, 9 Then
End Else
Error = EADM.CANTWRITE
Goto Exit.RepUnSubscribe
End
End
If SubType = "MD" Then
Gosub RepDistFileAdminClear
End
Open '', "UV_UDRSYS" To UvSysFvar Else
Error = EADM.CANTOPEN
Goto Exit.RepUnSubscribe
End
Read SysRecord From UvSysFvar, SysKey Else
Error = EADM.CANTREAD
Goto Exit.RepUnSubscribe
End
SystemName = SysRecord<1>
Locate SubKey In SysRecord<4> Setting Pos Then
Del SysRecord<4, Pos>
If SysRecord<4> = "" Then
* Send a message to the subscription system not to schedule
* Get Log State for the subscription system
RECIO(LogState, RPINFO$REP.STATE, RECIO$RPINFO)
If LogState Then
Error = UDRsetshmmessage(UDR.REPDELSYS, SysKey, 0, 0, UDRREP)
If Error Then
Error = EADM.BADCALL
End
End
End
End
Write SysRecord To UvSysFvar, SysKey Else
Error = EADM.CANTWRITE
Goto Exit.RepUnSubscribe
End
ConId = RPC.CONNECT(SystemName, UDR.SERVICE)
If ConId Then
* Send the remove call to the publisher
CALL.ARGS(1,1) = UDR.SRV.REMSUB ; * RemPubs
CALL.ARGS(1,2) = UVRPC.INT
CALL.ARGS(2,1) = PubKey
CALL.ARGS(2,2) = UVRPC.STRING
CALL.ARGS(3,1) = MachineName
CALL.ARGS(3,2) = UVRPC.STRING
CALL.ARGS(4,1) = SubKey
CALL.ARGS(4,2) = UVRPC.STRING
* make execute call
If RPC.CALL(ConId, " ", 4, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
OutData = RES.ARGS(3,1)
End Else
Error = STATUS() - 80000
End
ConId = RPC.DISCONNECT(ConId)
End Else
Error = Status() - 80000
End
End Else If UnSubType = "Q" Then
Find File In SubRecord<10> Setting Pos Then
If SubRecord<11,Pos> EQ Account Then
Del SubRecord<14, Pos> ; * these are deleted in reverse order because array shrinks with delete
Del SubRecord<13, Pos>
Del SubRecord<12, Pos>
Del SubRecord<11, Pos>
Del SubRecord<10, Pos>
Write SubRecord To UvSubFvar, SubKey Else
Error = EADM.CANTWRITE
End
End Else
Error = EADM.BADFILE
End
End Else
Error = EADM.BADFILE
End
End Else
Error = EADM.UDRINVALIDFILE
End
Close UvSubFvar
Exit.RepUnSubscribe:
Return
***********************************************************************
* RepUpdatePublishedFile - Updates the published file information
*
* Input: New publications details
* Params<1> = publication ID
* Params<2> = publication description
* Params<3> = system access list
* Params<4> = dictionary pub ID or 0
* Output: NONE
* Note: This function doesn't support changing the description for a
* Q-pointer publication at this time.
***********************************************************************
RepUpdatePublishedFile:
Error = 0
PubKey = Params<1>
Description = Params<2>
AccessList = Params<3>
PubRecord = ""
Open '', "UV_UDRPUB" To UvPubFvar Then
Readu PubRecord From UvPubFvar, PubKey Then
PubRecord<3> = Description
PubRecord<6> = AccessList
Write PubRecord On UvPubFvar, PubKey Else
Error = EADM.CANTWRITE
End
End Else
Error = EADM.CANTREAD
End
Close UvPubFvar
End Else
Error = EADM.CANTOPEN
End
Return
***********************************************************************
* RepUpdateRepSystem - Updates the Rep system information
*
* Input: New Rep system details
* Output: NONE
***********************************************************************
RepUpdateSystem:
Error = 0
SysKey = Params<1>
HotStandby = Params<5>
Rec = ""
LogState = 0
* Check the hot standby state must sure that is the hot standby state
* is changing to not being hot standby that there are no hot standby
* subscribers.
Open '', "UV_UDRSYS" To UvSysFvar Then
Readu Rec From UvSysFvar, SysKey Then
If Trim(Rec<4>) NE "" Then
If Rec<5> Then
* Check the hotstandby state make sure that if the hotstandby state
* is changing to not being hot standby that there are no hot standby
* subscribers.
If Not(HotStandby) Then
EXECUTE "SELECT UV_UDRSUB WITH HOTBACKUP NE 0 AND PUB_SYS EQ ":SysKey
If @SELECTED Then
Error = EADM.ACTIVESUBS
Goto Exit.UpdateRepSys
End
End
End
If Rec<3> NE Params<3> Then
* Send upate message to daemon
* Get Log State for the subscription system
RECIO(LogState, RPINFO$REP.STATE, RECIO$RPINFO)
* Test to see if the daemon is running
If LogState Then
Error = UDRsetshmmessage(UDR.REPUPDSYS, SysKey, 0, 0, UDRREP)
If Error Then
Error = EADM.BADCALL
End
End
End
End
Rec<2> = Params<2>
Rec<3> = Params<3>
Rec<5> = HotStandby
Write Rec On UvSysFvar, SysKey Else
Error = EADM.CANTWRITE
End
End Else
Error = EADM.CANTREAD
End
Close UvSysFvar
End Else
Error = EADM.CANTOPEN
End
Exit.UpdateRepSys:
Return
***********************************************************************
* RepUpdateSubscription - Updates the subscription information
*
* Input: New Subscription details
* Output: NONE
* Note: This function doesn't support changing the description for a
* Q-pointer subscription at this time.
***********************************************************************
RepUpdateSubscription:
Error = 0
SubKey = Params<1>
Description = Params<2>
HotStandby = Params<3>
PubKey = ""
SysKey = ""
Rec = ""
Open '', "UV_UDRSUB" To UvSubFvar Then
Readu Rec From UvSubFvar, SubKey Then
PubKey = Rec<4>
SysKey = Rec<5>
* Check to see if the subscription is a hot standby one if
* it is, check to see if there is already a hot standby for the
* publication file specified.
If HotStandby Then
EXECUTE "SELECT UV_UDRSUB WITH PUB_KEY = ":PubKey:" AND WITH HOTBACKUP NE '' AND WITH PUB_SYS = ":SysKey:" AND WITH @ID NE ":SubKey
IF @SELECTED Then
Error = EADM.PUBHASHOTBACKUP
Goto Exit.UpdateSubscription
End
End
Rec<3> = Description
Rec<7> = HotStandby
Write Rec On UvSubFvar, SubKey Else
Error = EADM.CANTWRITE
End
End Else
Error = EADM.CANTREAD
End
Close UvSubFvar
End Else
Error = EADM.CANTOPEN
End
Exit.UpdateSubscription:
Return
******************************************************************************
* RepVersionInfo - Receives the replication Admin client version info and
* returns the replication server version info.
*
* Input: Replication version that the client supports.
* Output: Replication version that the server supports.
******************************************************************************
RepVersionInfo:
RepAdminClientVersion = Params<1>
OutData<-1> = RepServerVersion
Return
********************************************************************
* ResetSpooler - Resets the spooler daemon
* Unix only
* Input: NONE
* Output: NONE
********************************************************************
ResetSpooler:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
GoSub CheckSpooler
If Error # 0 Then
Return
End
ExLine = USA.PATH : " -R"
GoSub ShellCommand
End
************************
* OS specific code end *
************************
Return
********************************************************************
* ResolveDeadLock - Resolve a current deadlock
*
* Input: User No
* Output: NONE
********************************************************************
ResolveDeadLock:
Error = 0
Userno = 0
* Using the -victim option from and the pid from the client
* remove the problem process.
Userno = Params<1>
ExLine:= UVHOMEBIN:"uvdlockd -victim ":Userno
GoSub ShellCommand
Return
**********************************************************************
* RollFwdToFile - Perform rollforward updates, redirecting
* output to uvrolf.info file
*
* Input: Command line arguments for uvrolf
* Output: Contents of uvrolf.res file
**********************************************************************
RollFwdToFile:
RollfParams = Trim(Params)
ResFile = UV.ROOT : OS.SEP : "uvrolf.res"
* First delete the uvrolf.res file
ExLine = RM.CMD : " -f " : ResFile
Gosub ShellCommand
* Now do the rollforward. This could take some time
ExLine = "uvrolf " : RollfParams
Gosub UvCommand
* Now return the contents of the uvrolf.res file
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
ExLine = "cat "
End Else
ExLine = "type "
End
************************
* OS specific code end *
************************
ExLine := ResFile
Gosub ShellCommand
OutData = Out
Return
**********************************************************************
* SaveDeadLockConfig - Saves the dead locking config information
*
* Input: Deadlock config information
* Output: None
**********************************************************************
SaveDeadLockConfig:
rec=""
line = ""
ReturnCode = 0
line.no = 0
eof = 0
found.start = 0
found.timer = 0
found.resolve = 0
found.logdir = 0
* Load client values.
timer = Params<1>
startval = Params<2>
res.strategy = Params<3>
log.directory = Params<4>
* Open the uvdlockd config file.
config.file = UVHOME : OS.SEP : "uvdlockd.config"
OpenSeq config.file To FConfig.file Then
* Parse the current values from the file and replace with the new values
Loop
ReadSeq line From FConfig.file else eof = 1
Until eof Do
Begin Case
Case line[1,3]='sta'
line="start=":startval
found.start = 1
Case line[1,3]='tim'
line="timer=":timer
found.timer = 1
Case line[1,3]='res'
line="res=":res.strategy
found.resolve = 1
Case line[1,3]='log'
line="log=":log.directory
found.logdir = 1
Case 1
line=line
End Case
line.no += 1
rec< line.no > = line
repeat
CloseSeq FConfig.file
* If the entry was not found add it.
If found.start = 0 Then
line.no +=1
rec<line.no>="start=":startval
End
If found.timer = 0 Then
line.no += 1
rec<line.no> = "timer=":timer
End
If found.resolve = 0 Then
line.no += 1
rec<line.no> = "res=":res.strategy
End
If found.logdir = 0 Then
line.no += 1
rec<line.no> = "log=":log.directory
End
OpenSeq config.file TO FConfig.file Else
ReturnCode = EADM.NOFILE
End
FOR i = 1 TO line.no
WriteSeq rec< i > TO FConfig.file else
ReturnCode = EADM.CANTWRITE
End
Next i
End
Else
* We could not open the file, we assume that it is
* not there and create it
Create FConfig.file Then
rec=""
rec<1>="start=":startval
rec<2>="timer=":timer
rec<3>="res=":res.strategy
rec<4>="log=":log.directory
Convert @FM To Char(10) in rec
WriteSeq rec To FConfig.file Else
ReturnCode =EADM.CANTWRITE
End
CloseSeq FConfig.file
End Else
ReturnCode = EADM.CANTCREATE
End
End
Error = ReturnCode
Return
************************************************************************
* SaveNodes - Save nodes to /etc/hosts (unix only)
* If the node is a new node, the client will
* already have checked for duplicates
*
* Input: Key - 1 Add node
* 2 Delete
* 3 Modify
* Node name
* IP address
* New node name (Modify only)
* New IP address (Modify only)
* Output: NONE
************************************************************************
SaveNodes:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Key = Params<1>
NodeName = Params<2>
IPAddr = Params<3>
If Key = 3 Then
NewNodeName = Params<4>
NewIPAddr = Params<5>
End
Gosub ReadAndConvertHosts
If Error = 0 Then
Begin Case
Case Key = 1
* Add a node - this can either be a synonym for an existing
* IP address, or a completely new node
Find IPAddr In HostData Setting i, j, k Then
HostData<i, 2, -1> = NodeName
End Else
HostData<-1> = IPAddr : @vm : NodeName
End
Case Key = 2
* Delete a node - this may just mean deleting a synonym
* or may mean deleting the whole node
Find NodeName In HostData Setting i, j, k Then
Del HostData<i, 2, k>
If HostData<i, 2> = "" Then
Del HostData<i>
Del OrigHosts<i>
End
End
Case Key = 3
* Modify node:
*
* If the IP address has changed, remove the node
* name from the old IP address (removing the whole node if
* this was the only name there), check if the new IP address
* already exists - if it does, add the new node name to it,
* if it doesn't, create a new node.
*
* If the IP address hasn't changed, then the node name has,
* just find the node name and replace it with the new one
If IPAddr <> NewIPAddr Then
Find NodeName In HostData Setting i, j, k Then
Del HostData<i, 2, k>
If HostData<i, 2> = "" Then
Del HostData<i>
Del OrigHosts<i>
End
End
Find NewIPAddr In HostData Setting i, j, k Then
HostData<i, 2, -1> = NewNodeName
End Else
HostData<-1> = NewIPAddr : @vm : NewNodeName
End
End Else ; * Nodename change only
Find NodeName In HostData Setting i, j, k Then
HostData<i, 2, k> = NewNodeName
End
End
End Case
* Convert the data back into the hosts file format and put
* back comments, then write the data back to the hosts file
WriteHosts = HostData
For Index = 1 To Dcount(HostData, @fm)
If OrigHosts<Index>[1, 1] = "#" Then
WriteHosts<Index> = OrigHosts<Index>
End Else
Pos = Index(OrigHosts<Index>, '#', 1)
If Pos Then
WriteHosts<Index, -1> := OrigHosts<Index>[Pos, Len(OrigHosts<Index>)]
End
End
Next Index
Convert @sm:@vm:@fm To ' ':Char(9):Char(10) In WriteHosts
WriteU WriteHosts To ETC.FVAR, "hosts" Locked
Error = EADM.RECLOCKED
End Else
Error = EADM.CANTWRITE
End
End
End
************************
* OS specific code end *
************************
Return
************************************************************************
* SaveUVCommand - Saves one or more universe commands to the
* VOC as either a Sentence (one command) or a
* Paragraph (multiple commands)
*
* Input: Record name
* Record data: S or PA
* UniVerse command
* UniVerse command
* .....
* Output: NONE
************************************************************************
SaveUVCommand:
RecName = Params<1>
Pos = Index(Params, @fm, 1)
RecData = Params[Pos + 1, 9999]
Write RecData To VOC, RecName On Error
Error = EADM.CANTWRITE
End Locked
Error = EADM.RECLOCKED
End Else
Error = EADM.CANTWRITE
End
Return
**********************************************************************
* SetActiveFiles - Activates or deactivates a single file for
* transaction logging. If the file is a type 1
* or type 19 file, an error will be returned.
*
* Input: Key 1 - Activate
* 2 - De-activate
* File info:
* Account
* File
* Output: NONE
**********************************************************************
SetActiveFiles:
Key = Params<1>
If Key = 1 Then Key = 10 Else Key = 11 ; * don't prompt from log_main
Account = Params<2, 1>
FileName = Params<2, 2>
* Look at file name to find out if it is a file, a dictionary (D_)
* or a PICK dictionary (P_)
DictPart = ""
If FileName[1,2] = "D_" Then
DictPart = "DICT"
FileName = FileName[3, Len(FileName)]
FileType = 1
End Else If FileName[1,2] = "P_" Then
DictPart = "PDICT"
FileName = FileName[3, Len(FileName)]
FileType = 2
End Else
FileType = 0
End
ExLine = 'log_main ':Key:' ':Account:' ':FileType:' '
ExLine := DictPart:' ':FileName:''
Gosub UvCommand
* Check for error returned because file was type 1 or type 19
If Index(Out, "A type 1 or 19 file", 1) # 0 Then
Error = EADM.TYPE1OR19
End Else
* Now check for success, otherwise return error and error text
If Index(Out, "Activating File ", 1) = 0 Then
Error = EADM.ACTIVATEFAILED
OutData = Trim(Out)
End
End
Return
**********************************************************************
* SetLogFiles - Add or drop logs
*
* Input: Key: 1 - Add logs
* 2 - Drop logs
* Number of logs to add/drop
* Log file size (if Key = 1)
* Output: NONE
**********************************************************************
SetLogFiles:
Key = Params<1>
NumFiles = Params<2>
If (Key = "1") Then
Startoff = Params<4>
End Else
Startoff = Params<3>
End
If DEBUGGING Then
LogText = "Key = ":Key
Gosub WriteDbg
LogText = "Startoff = ":Startoff
Gosub WriteDbg
LogText = "Params<3> = ":Params<3>
Gosub WriteDbg
LogText = "Params<4> = ":Params<4>
Gosub WriteDbg
End
If Startoff NE "" Then
If Key = "1" Then
FileSize = Params<3>
ExLine = "CREATE.LFILERAW " : FileSize : " " : NumFiles : " " : Startoff
End Else
* First get the logging state
LogState = ""
RECIO(LogState, FINFO$AI.STATE, RECIO$FINFO)
If DEBUGGING Then
LogText = "LogState = ":LogState
Gosub WriteDbg
End
* If the LogState is SHUTDOWN, then we use one type of
* algorithm to drop and reorder the logs. This state
* or UNINITAILIZED.
If LogState = AI$DISABLED OR LogState = AI$UNINIT OR LogState = AI$INACTIVE THEN
ExLine = "DELETE.LFILERAW " : NumFiles
End
Else If LogState = AI$LOGGING THEN
* If the LogState is ENABLED, then we only allow drop logs
* to logfiles when the offsets are sequenced from smallest
* to highest.
ExLine = "DELETE.LFILERAW2 " : NumFiles
End
Else
* Just report the error and return
Error = EADM.WRONGSTATE
Return
End
End
End
Else
If Key = "1" Then
FileSize = Params<3>
ExLine = "CREATE.LFILE " : FileSize : " " : NumFiles
End Else
ExLine = "DELETE.LFILE " : NumFiles
End
End
If DEBUGGING Then
LogText = "Key = ":Key
Gosub WriteDbg
LogText = "Startoff = ":Startoff
Gosub WriteDbg
LogText = "Params<3> = ":Params<3>
Gosub WriteDbg
LogText = "Params<4> = ":Params<3>
Gosub WriteDbg
End
If DEBUGGING Then
LogText = "ExLine before TCLCommand = ":ExLine
Gosub WriteDbg
LogText = "Out = ":Out
Gosub WriteDbg
End
*
* Execute the program choosen:
* VOC Actual Program
* ----------------------------------
* CREATE.LFILE -> CR.LFILE.B
* DELETE.LFILE -> DL.LFILE.B
* CREATE.LFILERAW -> CR.LFILERAW.B
* DELETE.LFILERAW -> DL.LFILERAW.B
* DELETE.LFILERAW2 -> DL.LFILER2.B
Gosub TCLCommand
If DEBUGGING Then
LogText = "ExLine = ":ExLine
Gosub WriteDbg
LogText = "Out = ":Out
Gosub WriteDbg
End
If Out # "" Then
Begin Case
Case Out[1,2] = "10" ; * Create file failed
Error = EADM.CANTCREATELOG
Case Out[1,2] = "36" ; * Bad RawOffset specified
Error = EADM.BADOFFSET
Case Out[1,2] = "39" ; * Logging in wrong state
Error = EADM.WRONGSTATE
Case Out[1,2] = "40"
Error = EADM.DROPRAWLOG ; * Drop log failed
Case Out[1,2] = "41"
Error = EADM.DROPRAWLOG2 ; * Drop log failed
Case 1
* success
End Case
If DEBUGGING Then
LogText = "Error = ":Error
Gosub WriteDbg
End
End
Return
**********************************************************************
* SetLoggingConfig - Makes changes to transaction logging config
* If logdir hasn't changed it will be null. If
* the log directory is being changed and the
* directory it is being changed to already exists,
* an error will be returned so that the client
* can ask the user if they want to use this dir.
* If they do want to use it, SetLoggingConfig will
* be called a second time with the "Use existing
* directory" flag set to true
*
* Input: Log directory (or null)
* Use existing directory (or null)
* Checkpoint flag
* Archive flag
* Archive type (only if Archive flag = 1)
* 0 - disk
* 1 - tape
* Device list (only if Archive type = 1)
* Output: NONE
**********************************************************************
SetLoggingConfig:
LogDir = Params<1>
UseExistingDir = Params<2>
If Params<3> = "1" Then
CheckpointMode = "ON"
End Else
CheckpointMode = "OFF"
End
If Params<4> = "1" Then
ArchiveMode = "ON"
End Else
ArchiveMode = "OFF"
End
ArchiveType = Params<5>
DevList = Params<6>
*
* This field is simply filled in when a raw device is used
* LogDir will still be used for Unix logs directory
*
RawDir = Params<7>
If DEBUGGING Then
LogText = "RawDir = ":RawDir
Gosub WriteDbg
End
If RawDir NE "" Then
ExLine = CDIR.EXECRAW : RawDir : " 1"
Gosub TCLCommand
Out = Trim(Out[1, Len(Out) - 1])
If Out # "" Then
Begin Case
Case Out = "0" ; * Directory already exists
If UseExistingDir = 0 Then
* This is the first time in here - set an error so the client
* can ask the user if they want to use this directory
Error = EADM.DIREXISTS
End Else
* Second time in, the user wants to use existing dir
Open 'DICT', "UV_LOGS" To LogFvar Then
Rec = "X" : @fm : RawDir
Write Rec On LogFvar, LOGS.RAWDIR Else
Error = EADM.CANTWRITE
End
End Else
Error = EADM.CANTOPEN
End
End
Case Out = "1"
Error = EADM.BADPATH
Case Out = "2"
Error = EADM.BADRAWDEV
Case 1
* Create log directory worked
End Case
End
End
If LogDir # "" Then
ExLine = CDIR.EXEC : LogDir : " 1" ; * "1" says we are sysadmin
Gosub TCLCommand
Out = Trim(Out[1, Len(Out) - 1])
If Out # "" Then
Begin Case
Case Out = "0" ; * Directory already exists
If UseExistingDir = 0 Then
* This is the first time in here - set an error so the client
* can ask the user if they want to use this directory
Error = EADM.DIREXISTS
End Else
* Second time in, the user wants to use existing dir
Open 'DICT', "UV_LOGS" To LogFvar Then
Rec = "X" : @fm : LogDir
Write Rec On LogFvar, LOGS.DIR Else
Error = EADM.CANTWRITE
End
End Else
Error = EADM.CANTOPEN
End
End
Case Out = "1"
Error = EADM.BADPATH
Case 1
* Create log directory worked
End Case
End
End
If Error = 0 Then
ExLine = "SET.LOG.ATTR CHECKPOINT " : CheckpointMode
ExLine := " ARCHIVE ": ArchiveMode
If ArchiveType = 1 Then ; * Tape
ExLine := " DEVICELIST " : Convert(@vm, " ", DevList)
End
Gosub TCLCommand
End
Return
************************************************************************
* SetRPCPort - Sets RPC port number unix only
*
* Input: Port number
* Output: NONE
************************************************************************
SetRPCPort:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
PortNo = Params<1>
PortString = "uvrpc"
PortComment = "# uvNet rpc port"
Gosub SetPort
End
************************
* OS specific code end *
************************
Return
*********************************************************************
* SetPrinterGroup - Creates, modifies or deletes a printer group
* Unix only
*
* Input: Printer group data
* Output: NONE
**********************************************************************
SetPrinterGroup:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
PGroups = Params
PGroupFile = SPOOL.DIR:"/print_group"
OpenSeq PGroupFile To PGroupFvar Else
Create PGroupFvar Else
Error = EADM.CANTOPEN
Return
End
End
Status FileStats From PGroupFvar Then
PGroupPerms = Oconv(FileStats<5>, "MO")[4,3]
End Else
PGroupPerms = 0
End
Convert @VM:@SM To ":":"," In PGroups
NumPGroups = DCount(PGroups, @FM)
For I = 1 To NumPGroups
WriteSeq PGroups<I> On PGroupFvar Else
Error = EADM.CANTWRITE
CloseSeq PGroupFvar
Return
End
Next I
WEOFSeq PGroupFvar
CloseSeq PGroupFvar
If PGroupPerms # 644 Then
ExLine = "/bin/chmod 644 ":PGroupFile
GoSub ShellCommand
End
End
************************
* OS specific code end *
************************
Return
*******************************************************************************
* SetSpoolConfig - Sets spooler configuration parameters.
* There is also a flag to say whether the administrator
* wishes to restart the spooler
* Unix only
*
* Input: Spooler directory
* Error log path
* Activity log path
* Logging flag
* Chronological order flag
* Timer value
* Restart spooler flag
* Output: Result code: (only codes 0 & 1 will be
* returned if no restart was
* requested)
* 0 Changes succeeded
* 1 Failed to copy changes into place,
* restarted spooler with old settings
* (if restart specified)
* 2 Failed to copy changes into place,
* failed to restart spooler with old
* settings
* 3 Failed to restart with new settings,
* restarted with old settings, changes
* not saved
* 4 Failed to restart with new or old
* settings, changes not saved
*
* Other params are dependent on result:
*
* Result Extra params
*
* 0 path of saved uv.rc file
* 1 error from copy
* 2 error from copy
* error from restart
* erroneous usd command line
* 3 error from restart
* erroneous usd command line
* 4 error from first restart
* erroneous usd command line
*
*******************************************************************************
SetSpoolConfig:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
NewSpoolDir = Params<1>
NewErrLog = Params<2>
NewActLog = Params<3>
NewLogFlag = Params<4>
NewOrderFlag = Params<5>
NewTimerVal = Params<6>
RestartFlag = Params<7>
NewUSDScript = USD.SCRIPT
* First validate the parameters
OpenPath NewSpoolDir To TFile Else
Error = EADM.BADSPOOLDIR
Goto ExitSetSpoolConfig
End
Close TFile
* Error log and Activity log can either be directory paths or
* file names - if the path given cannot be opened, assume its
* a non-existant file name and try to open the directory above it
OpenPath NewErrLog To TFile Else
If NewErrLog[Len(NewErrLog)] = "/" Then
NewErrLog = NewErrLog[1, Len(NewErrLog) - 1]
End
Levels = Count(NewErrLog, "/")
TempPath = NewErrLog[1, Index(NewErrLog, "/", Levels)]
OpenPath TempPath To TFile Else
Error = EADM.BADERRLOG
Goto ExitSetSpoolConfig
End
End
Close TFile
OpenPath NewActLog To TFile Else
If NewActLog[Len(NewActLog)] = "/" Then
NewActLog = NewActLog[1, Len(NewActLog) - 1]
End
Levels = Count(NewActLog, "/")
TempPath = NewActLog[1, Index(NewActLog, "/", Levels)]
OpenPath TempPath To TFile Else
Error = EADM.BADACTLOG
Goto ExitSetSpoolConfig
End
End
Close TFile
* Validation over, get down to work If the administrator wanted
* to restart the spooler, stop it before writing to the uvrc
* file and start it again when we've finished.
If UVRC.OPEN = False Then
OpenSeq UVRCFILE To UVRC Else
Error = EADM.CANTOPENUVRC
Goto ExitSetSpoolConfig
End
UVRC.OPEN = True
End
If RestartFlag = 1 Then
ExLine = USA.PATH:" -z"
GoSub ShellCommand
End
* Open a temporary file to create a new uvrc file into
OpenNewfile:
NewUvrc = "/tmp/sp":Date():".":Time()
OpenSeq NewUvrc To OutFile Else
Create OutFile Else
Error = EADM.CANTOPENTMPFL
Goto ExitSetSpoolConfig
End
Goto OpenNewfile
End
* Go through the uvrc file searching for the 4 lines which
* contain spooler configuration info - the logic for this
* section of code is taken from the SP.PARAMS.B module
EOF = False
Loop
ReadSeq Line From UVRC Else EOF = True
Until EOF
SplLine = (Index(Line, "spoolDIR", 1) And Index(Line, "=", 1))
ErrLine = (Index(Line, "errlogDIR", 1) And Index(Line, "=", 1))
ActLine = (Index(Line, "actlogDIR", 1) And Index(Line, "=", 1))
UsdLine = (Index(Line, "bin/usd", 1))
NewLine = Line
Begin Case
* NOTE: the ordering of the cases is important - ErrLine and
* ActLine MUST come before SplLine as SplLine will also be
* set for those lines
Case ErrLine
* Check to see if error log path is the same as spool dir
EqIndex = Index(Line, "=", 1)
If NewErrLog = NewSpoolDir Then
NewLine = Line[1, EqIndex]:"$spoolDIR"
End Else
NewLine = Line[1, EqIndex]:NewErrLog
End
NewUSDScript<2> = Trim(NewLine)
Case ActLine
* Check to see if activity log path is the same as spool dir
EqIndex = Index(Line, "=", 1)
If NewActLog = NewSpoolDir Then
NewLine = Line[1, EqIndex]:"$spoolDIR"
End Else
NewLine = Line[1, EqIndex]:NewActLog
End
NewUSDScript<3> = Trim(NewLine)
Case SplLine
* This code is taken directly from SP.PARAMS.B. What it
* appears to be doing is checking whether the new value
* of Spool Dir is the same as that held in the .uvconfig
* file - if it is, then the spoolDIR variable is got by
* extracting the value from the .uvconfig file, if it is
* different, then it is just set to the value given by the user
Tunable = "`bin/analyze.shm -t0 | grep UVSPOOL | cut -d= -f2`"
ExLine = "bin/analyze.shm -t0 | grep UVSPOOL | cut -d= -f2"
GoSub ShellCommand
EqIndex = Index(Line, "=", 1)
If Out<1> = NewSpoolDir Then
NewLine = Line[1, EqIndex]:Tunable
End Else
NewLine = Line[1, EqIndex]:NewSpoolDir
End
NewUSDScript<1> = Trim(NewLine)
Case UsdLine
* Set up the usd command line. If error log or activity
* log are different to spooldir, specify them on the
* command line
NewLine = Line[1, UsdLine-1]:"bin/usd $spoolDIR"
If NewErrLog # NewSpoolDir Then
NewLine := " -e $errlogDIR"
End
If NewActLog # NewSpoolDir Then
NewLine := " -a $actlogDIR"
End
If NewLogFlag = 1 Then
NewLine := " -L"
End
If NewOrderFlag = 1 Then
NewLine := " -t"
End
If NewTimerVal # "10" Then
NewLine := " -w ":NewTimerVal
End
NewUSDScript<4> = Trim(NewLine)
End Case
WriteSeq NewLine To OutFile Else
Error = EADM.CANTWRITEUVRC
CloseSeq OutFile
Goto ExitSetSpoolConfig
End
Repeat
CloseSeq UVRC
UVRC.OPEN = False
CloseSeq OutFile
* Now copy the new file over the original uvrc file, making
* a copy of the original in /tmp/uvrcDATE.TIME
TmpFile = "/tmp/uvrc":Date():".":Time()
ExLine = "cp ":UVRCFILE:" ":TmpFile:OS.CMDSEP:" cp ":NewUvrc:" ":UVRCFILE
ExLine := OS.CMDSEP:" rm ":NewUvrc
GoSub ShellCommand
If Out # "" Then
CopyErr = Out
If RestartFlag Then
* Copy failed, restart using original usd script
ExLine = Convert(@FM, ";", USD.SCRIPT) : " sleep 3"
GoSub ShellCommand
If Out # "" Then
OutData<1> = 2 ; * copy and restart failed
OutData<2> = CopyErr ; * error from copy
OutData<3> = Out ; * error from restart
OutData<4> = ExLine ; * erroneous usd script
Goto ExitSetSpoolConfig
End
End
OutData<1> = 1 ; * copy failed
OutData<2> = CopyErr ; * error from copy
Goto ExitSetSpoolConfig
End Else
If RestartFlag Then
* Copy worked, restart using new usd script
ExLine = Convert(@FM, ";", NewUSDScript) : " sleep 3"
GoSub ShellCommand
If Out # "" Then
* Restart with new script failed, restore uvrc and
* restart with original usd script
RestartErr = Out
RestartScript = ExLine
ExLine = "mv ":TmpFile:" ":UVRCFILE
GoSub ShellCommand
ExLine = Convert(@FM, ";", USD.SCRIPT) :" sleep 3"
GoSub ShellCommand
If Out # "" Then
OutData<1> = 4 ; * Failed to restart
OutData<2> = Out ; * error from restart
OutData<3> = ExLine ; * erroneous usd script
End Else
OutData<1> = 3 ; * Restarted original
OutData<2> = RestartErr ; * error from new restart
OutData<3> = RestartScript ; * erroneous usd script
End
Goto ExitSetSpoolConfig
End
End ; * If RestartFlag
End
OutData<1> = 0 ; * everything worked
OutData<2> = TmpFile ; * path of saved uv.rc file
ExitSetSpoolConfig:
GoSub InitSpooler ; * Re-initialize spooler variables in named common
End
************************
* OS specific code end *
************************
Return
************************************************************************
* SetTelnetInfo - Sets telnet data - only the items which have
* been changed will have values. NT only
*
* Input: Telnet port number (or null)
* User policy (or null)
* (0 - attach to home account
* 1 - attach to home directory
* 2 - attach to any account
* 3 - attach to any directory)
* Max. logon attempts (or null)
* Logon pause (seconds) (or null)
* Logon timeout (seconds) (or null)
* Termination pause (seconds) (or null)
* Output: NONE
************************************************************************
SetTelnetInfo:
**************************
* OS specific code start *
**************************
If OS.TYPE <> "UNIX" Then
DECLARE GCI UVREGputint
PortNo = Params<1>
UserPolicy = Params<2>
MaxLogon = Params<3>
LogonPause = Params<4>
LogonTimeout = Params<5>
TermPause = Params<6>
If PortNo # "" Then
PortString = "uvtelnet"
PortComment = "# uniVerse telnet port"
Gosub SetPort
End
If Error = 0 And UserPolicy # "" Then
Result = UVREGputint("UserPolicy", UserPolicy)
If Result # 0 Then
Error = EADM.CANTWRITE
End
End
If Error = 0 And MaxLogon # "" Then
Result = UVREGputint("MaxLogonAttempts", MaxLogon)
If Result # 0 Then
Error = EADM.CANTWRITE
End
End
If Error = 0 And LogonPause # "" Then
Result = UVREGputint("LogonPause", LogonPause)
If Result # 0 Then
Error = EADM.CANTWRITE
End
End
If Error = 0 And LogonTimeout # "" Then
Result = UVREGputint("LogonTimeout", LogonTimeout)
If Result # 0 Then
Error = EADM.CANTWRITE
End
End
If Error = 0 And TermPause # "" Then
Result = UVREGputint("TerminationPause", TermPause)
If Result # 0 Then
Error = EADM.CANTWRITE
End
End
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* SetupDiagnosicsRun - Setup the file fix diagnosics system
*
* Input: Diag details
* Output:
**********************************************************************
SetupDiagnosicsRun:
Dim CALL.ARGS(10,2)
Dim RES.ARGS(20,2)
Output = ""
FixFilename = Params<1>
FixFilePath = Params<2>
FileFixLevel = Params<3>
FileFixFix = Params<4>
FileFixErrorLevel = Params<5>
FileFixOutput = Params<6>
FileFixOutputPath = Params<7>
FileFixLogging = Params<8>
FileFixLoggingPath = Params<9>
If FileFixOpen = 0 Then
Gosub StartFileFixServer
End
If Not(Error) Then
* We are ok, start the call
* First Open the File
Gosub OpenFileFixFile
If Not(Error) Then
* Setp the subsystem
Gosub SetupFileFix
If Not(Error) Then
* Setup the logging
Gosub SetupLoggingFileFix
End
End
End
Return
************************************************************************
* SetUVConfig - Write new configuration parameters back to
* the uvconfig file
*
* Input: Array of Param name, Param value pairs
* Output: NONE or Validation error
************************************************************************
SetUVConfig:
FileName = UVHOME:OS.SEP:"uvconfig"
KeepFileOpen = True
Gosub ReadSeqFile
Dc = Dcount(Params, @fm)
For I = 1 to Dc
ParamName = Params<I,1>
ParamValue = Params<I,2>
Occur = 1
Loop
FindStr ParamName In NewText,Occur Setting Pos Else
Pos = -1
End
Until Pos < 0 Or NewText<Pos>[1,1] # COMMENT$CHAR Do
Occur += 1
Repeat
If Pos < 0 Then
NewText<-1> = ParamName:" ":ParamValue
End Else
NewText<Pos> = ParamName:" ":ParamValue
End
Next I
UnixFileOpen = True
Gosub WriteSeqFile
ExLine = "uvregen"
Gosub UvCommand
* If result of uvregen command starts with "uvregen:" then it worked,
* otherwise pass the error message back as its probably a validation
* error
If Out[1, 8] = "uvregen:" Then
OutData = ""
End Else
OutData = Out
Error = EADM.UVREGENFAILED
End
Return
*******************************************************************************
* ShmGetProgSize: - returns the size in bytes of a program
*
* Input: Account @FM File @FM Program name
* Output: Prog size
*******************************************************************************
ShmGetProgSize:
Account = Params<1>
File = Params<2>
Prog = Params<3>
ExLine = "get_prog_size ":Account:" ":File:" ":Prog
GoSub UvCommand
* Extract size from the output. If the size couldn't be worked out,
* then it will be set to -1, we should return "?"
If Field(Out, " ", 1) = "0" Then
Size = Field(Out, " ", 3)
If Size = -1 Then Size = "?"
End Else
Size = "?"
End
OutData = Size
Return
******************************************************************************
* ShmListSHMTOLOAD: - Gets data pertaining to the SHM.TO.LOAD file.
* First works out the maximum size of the shared
* memory segment, then, for each entry in the
* SHM.TO.LOAD file, works out the size of the program
*
* Input: NONE
* Output: Max size of shmseg
* Dynamic array of Account, File, Prog, Size
******************************************************************************
ShmListSHMTOLOAD:
* Check if we have access to the SHM.TO.LOAD file - if it exists
* but we don't have access, return an error. If it doesn't exist,
* this isn't a problem as it will be created in ShmWriteSHMTOLOAD
ShmPath = UVHOME : OS.SEP : SHM.TO.LOAD
If access(ShmPath, R$OK + W$OK) Then ; * Can't access, check why
If Not(access(ShmPath, F$OK)) Then
Error = EADM.NOACCESS
Return
End
End
* Lock SHM.TO.LOAD file - this lock will be released either when
* we write new details or when the user presses CANCEL. Don't worry
* if the read fails, it means the file doesn't exist yet
Open "&UFD&" To UFDFvar Then
ReadU ShmData From UFDFvar, SHM.TO.LOAD Then
End
End Else
Error = EADM.CANTOPEN
Return
End
* Get maximum size for shared memory
ExLine = "get_shm_size"
GoSub UvCommand
OutData = Out
* Process each line in SHM.TO.LOAD - extract Account, File, Prog,
* then find the size of the program. If the size cannot be
* calculated, set size to "?"
NumProgs = DCount(ShmData, @FM)
For i = 1 To NumProgs
Acc = Field(ShmData<i>, @VM, 1)
Fil = Field(ShmData<i>, @VM, 2)
Prog = Field(ShmData<i>, @VM, 3)
ExLine = "get_prog_size ":Acc:" ":Fil:" ":Prog
GoSub UvCommand
If Field(Out, " ", 1) = "0" Then
Size = Field(Out, " ", 3)
If Size = -1 Then Size = "?"
End Else
Size = "?"
End
OutData<-1> = Acc :@VM: Fil :@VM: Prog :@VM: Size
Next i
Return
*******************************************************************************
* ShmLoad: - Load shared memory with the programs specified in SHM.TO.LOAD
*
* Input: Modification size
* Output: Results of calling load_shm_cat
*******************************************************************************
ShmLoad:
ModSize = Params
ExLine = "load_shm_cat ":ModSize
GoSub UvCommand
OutData = Change(Out,@fm,CRLF)
Error = False
Return
*****************************************************************************
* ShmModify: - Modifies programs running in shared memory
*
* Input: Depends on first argument:
*
* 1 <account> <file> <prog> - Delete item from shared
* memory
* 2 <account> <file> <prog> - Add item to shared memory
* 3 <account> <file> <prog> - Update item
* 4 - Remove shm program segment
* Output: NONE
*****************************************************************************
ShmModify:
Key = Params<1>
If Key = 4 Then ; * Remove shm segment
ExLine = "modify_shm ":Key
End Else
Account = Params<2>
File = Params<3>
Program = Params<4>
ExLine = "modify_shm ":Key:" ":Account:" ":File:" ":Program
End
Gosub UvCommand
If Out # "" Then
Error = EADM.SHMMODFAILED
End
Return
************************************************************************
* ShmReleaseLock - Releases lock on SHM.TO.LOAD file if user has
* not modified anything
*
* Input: NONE
* Output: NONE
************************************************************************
ShmReleaseLock:
Release UFDFvar, SHM.TO.LOAD
Close UFDFvar
Return
************************************************************************
* ShmRunning - returns list of programs running in shared mem
*
* Input: NONE
* Output: Total bytes
* Bytes used
* Dynamic array of Account, File, Prog
************************************************************************
ShmRunning:
ExLine = "smat -b"
Gosub UvCommand
* Check if shared memory is loaded - if not, the 'smat -b' command will
* have returned a null string
If Out = "" Then
OutData = ""
Return
End
* Shared memory IS loaded - dissect the output from smat -b. Format eg:
*
* State of shared memory: 4
* Number of programs loaded into shared memory: 3
* Size References Users Pathname
* 505 0 0
* 505 0 0 /pitest/uv831/catdir/!CATS
* 505 0 0 /pitest/uv831/catdir/!EQS
* Overhead for filenames: 346
* Shared basic memory total bytes: 2059; bytes used: 1861; remaining: 198
*
* But watch out for items that have been deleted (like the 1st one in
* the example above)
* First extract TotalBytes. Use ":" and ";" to find positions of
* the data we require, then we're not so language dependent
NumLines = DCount(Out, @FM)
ByteLine = Out<NumLines -1>
Pos = Index(ByteLine, ":", 1)
ByteLine = ByteLine[Pos + 1, Len(ByteLine) - Pos] ; * strip unwanted data
Pos = Index(ByteLine, ";", 1)
TotalBytes = Trim(ByteLine[1, Pos - 1])
* Then BytesUsed
Pos = Index(ByteLine, ":", 1)
ByteLine = ByteLine[Pos + 1, Len(ByteLine) - Pos] ; * strip used data
Pos = Index(ByteLine, ";", 1)
BytesUsed = Trim(ByteLine[1, Pos - 1])
* Load Account details (name & path) into array so we can use it
* to map pathnames to accounts
Done = False
I = 1
Select UVACCOUNT
NumAccounts = @SELECTED
Dim Accounts(NumAccounts, 2) ; * account name, account path
Loop
ReadNext RecId Else Done = True
Until Done
Readv AccPath From UVACCOUNT, RecId, 11 Then
**************************
* OS specific code start *
**************************
If OS.TYPE # "UNIX" Then
AccPath = Convert("\ABCDEFGHIJKLMNOPQRSTUVWXYZ", "/abcdefghijklmnopqrstuvwxyz", AccPath)
End
************************
* OS specific code end *
************************
Accounts(I, 1) = RecId
Accounts(I, 2) = AccPath
I = I + 1
End
Repeat
* Now dissect each program line in turn, discarding the deleted ones
ProgLines = Out[@FM, 5, NumLines - 7]
NumProgs = DCount(ProgLines, @FM)
OutData = TotalBytes :@FM: BytesUsed
For i = 1 To NumProgs
NumSpaces = Count(ProgLines<i>, " ")
Pos = Index(ProgLines<i>, " ", NumSpaces)
Path = ProgLines<i>[Pos + 1, Len(ProgLines<i>) - Pos]
If Path # "" Then
TempPath = Path
**************************
* OS specific code start *
**************************
If OS.TYPE # "UNIX" Then
* Change to unix style pathname
TempPath = Convert("\ABCDEFGHIJKLMNOPQRSTUVWXYZ", "/abcdefghijklmnopqrstuvwxyz", TempPath)
End
************************
* OS specific code end *
************************
* Split the pathname into account, file & program - not as
* straightforward as it could be - need to take into account
* type 1 files and account paths that don't have an entry
* in UV.ACCOUNTS.
* Start by assuming the simple case - this will be correct in
* 99% of cases. Last part of path is the program, second to
* last is the file, everything else is the account path -
* try to match it to an entry in UV.ACCOUNTS
NumFields = Count(TempPath, "/")
PathIndex = NumFields - 1
Pos = Index(TempPath, "/", PathIndex)
AccountPath = TempPath[1, Pos - 1]
GoSub FindAccountName
If AccountName <> "" Then ; * found it
Pos2 = Index(TempPath, "/", PathIndex + 1)
FileName = Path[Pos + 1, Pos2 - Pos - 1]
ProgName = Path[Pos2 + 1, 9999]
End Else
* Assume a type1 file is involved here, try to find the type1
* file in the path, then try to match the account from there
Type1Found = False
PathIndex = NumFields - 2
Loop
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Type1Path = AccountPath
ExLine = "ls -a ":Type1Path
End Else
Type1Path = Convert("/", "\", AccountPath)
ExLine = "dir /A ":Type1Path
End
************************
* OS specific code end *
************************
GoSub ShellCommand
If Index(Out, ".Type1", 1) Then ; * Type1 file found
Type1Found = True
Pos = Index(TempPath, "/", PathIndex)
AccountPath = TempPath[1, Pos - 1]
GoSub FindAccountName
End Else PathIndex = PathIndex - 1
Until Type1Found Or PathIndex <= 1 ; * always starts with "/"
Repeat
If Not(Type1Found) Then
Pos = Index(TempPath, "/", NumFields - 1)
Pos2 = Index(TempPath, "/", NumFields)
AccountName = Path[1, Pos - 1]
FileName = Path[Pos + 1, Pos2 - Pos - 1]
ProgName = Path[Pos2 + 1, 9999]
End Else ; * type1 found, may or may not have an account match
If AccountName = "" Then ; * no account match
AccountName = AccountPath
End
Pos2 = Index(TempPath, "/", PathIndex + 1)
FileName = Path[Pos + 1, Pos2 - Pos - 1]
ProgName = Path[Pos2 + 1, 9999]
**************************
* OS specific code start *
**************************
If OS.TYPE # "UNIX" Then
ProgName = Convert("\", "/", ProgName)
End
************************
* OS specific code end *
************************
ProgName = Change(ProgName, "/", "")
If ProgName[Len(ProgName), 1] = "?" Then
ProgName = ProgName[1, Len(ProgName) - 1]
End
End
End
OutData = OutData :@FM: AccountName :@VM: FileName :@VM: ProgName
End
Next i
Error = False
Return
*****************************************************************************
* ShmWriteSHMTOLOAD: - Clears the SHM.TO.LOAD file and writes the new
* Data to it
*
* Input: New contents of file
* Output: NONE
*****************************************************************************
ShmWriteSHMTOLOAD:
Write Params To UFDFvar, SHM.TO.LOAD Else
Error = EADM.CANTWRITE
End
Close UFDFvar
Return
**********************************************************************
* ShutdownDiagnosicsRun - Shutdown the file fix diagnosics system
*
* Input: Diag details
* Output:
**********************************************************************
ShutdownDiagnosicsRun:
Dim CALL.ARGS(10,2)
Dim RES.ARGS(20,2)
Output = ""
If FileFixOpen = 0 Then
Gosub StartFileFixServer
End
If Not(Error) Then
* We are ok, start the call
* Shutdown the subsystem
Gosub ShutdownFileFix
End
Return
************************************************************************
* SpoolActivityLog - Reads the last 4096 bytes from the activity log
* file
* Unix only.
*
* Input: NONE
* Output: Data from activity log
************************************************************************
SpoolActivityLog:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
GoSub GetActLogPath
If Error # 0 Then
Return
End
OpenSeq ActLogFile To ActFvar Else
Error = EADM.NOFILE
Return
End
NewText = ""
* In case the file is huge, seek to the end and go back 16k
* bytes. Ignore the outcome of this - if it fails, it means
* the file isn't that long, so just read the whole file.
* NB. Can't return more data than this at the moment due to
* RPC package size limitations
Seek ActFvar, -16384, 2 Then
End
Done = False
Loop
ReadSeq Line From ActFvar Else Done = True
Until Done or Status() Do
NewText<-1> = Line
Repeat
CloseSeq ActFvar
OutData = Change(NewText, @FM, CRLF)
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* SpoolContinue - Continues a held printer
* Unix only
*
* Input: Printer name
* Output: NONE
**********************************************************************
SpoolContinue:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
GoSub CheckSpooler
If Error # 0 Then
Return
End
ExLine = USA.PATH:" -c -p ":Params
Gosub ShellCommand
End
************************
* OS specific code end *
************************
Return
************************************************************************
* SpoolErrorLog - Reads the last 4096 bytes of the error log
* file
* Unix only
*
* Input: NONE
* Output: Data from error log
************************************************************************
SpoolErrorLog:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
GoSub GetErrLogPath
If Error # 0 Then
Return
End
OpenSeq ErrLogFile To ErrFvar Else
Error = EADM.NOFILE
Return
End
NewText = ""
* In case the file is huge, seek to the end and go back 16k
* bytes. Ignore the outcome of this - if it fails, it means
* the file isn't that long, so just read the whole file.
* NB. Can't return more data than this at the moment due to
* limitations in RPC packet size
Seek ErrFvar, -16384, 2 Then
End
Done = False
Loop
ReadSeq Line From ErrFvar Else Done = True
Until Done or Status() Do
NewText<-1> = Line
Repeat
CloseSeq ErrFvar
OutData = Change(NewText, @FM, CRLF)
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* SpoolJobControl - Performs job control functions to:
* put a job on hold
* release a held job
* remove a job from the print queue
* reprint a job
* Unix only
*
* Input: Action key: 1 - Hold
* 2 - Cancel
* 3 - Release
* 4 - Reprint
* JobNo
* Output: NONE
**********************************************************************
SpoolJobControl:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
ControlKey = Params<1>
JobNo = Params<2>
GoSub CheckSpooler
If Error # 0 Then
Return
End
** Check the job exists
GoSub GetSpoolDetails
Locate JobNo In JobIndex Setting Pos Else
Error = EADM.NOPRINTJOB
Return
End
Begin Case
Case ControlKey = 1 ; * Hold
ExLine = USM.PATH:" -h ":JobNo
Gosub ShellCommand
Case ControlKey = 2 ; * Cancel
ExLine = USM.PATH: " -k ":JobNo
Gosub ShellCommand
Case ControlKey = 3 ; * Release
ExLine = USM.PATH:" -r ":JobNo
Gosub ShellCommand
Case ControlKey = 4 ; * Reprint
ExLine = USM.PATH:" -q ":JobNo
GoSub ShellCommand
ExLine = USM.PATH:" -r ":JobNo
GoSub ShellCommand
End Case
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* SpoolMount - Mounts a form on a printer
* Unix only
*
* Input: Printer name
* Form name
* Output: NONE
**********************************************************************
SpoolMount:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
GoSub CheckSpooler
If Error # 0 Then
Return
End
PrinterName = Params<1>
FormName = Params<2>
If Upcase(FormName) = "[NULL]" Then
FormName = '""'
End
ExLine = USA.PATH:" -F ":FormName: " -p ":PrinterName
Gosub ShellCommand
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* SpoolPrintedAt - Searches the activity log file information
* about jobs printed, using the supplied search
* parameters
* Unix only
*
* Input: Filename
* JobID
* User
* Output: Array of data from activity log:
* JobId
* UID
* File
* Time
* Printer
**********************************************************************
SpoolPrintedAt:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
SearchFile = Params<1>
SearchJobid = Params<2>
SearchUser = Params<3>
* If a user name has been given as one of the search criteria, then
* try to convert it to a user id
If SearchUser <> "" Then
ExLine = \grep "^\:SearchUser:\:" /etc/passwd | cut -d":" -f3\
GoSub ShellCommand
If Out <> "" Then
SearchUser = Out<1>
End
End
* Now open the activity log and for each line starting with "P"
* (printer information), check search criteria. If it matches
* all the search criteria, add it to the output array
GoSub GetActLogPath
If Error # 0 Then
Return
End
OpenSeq ActLogFile To ActFvar Then
Done = False
Loop
ReadSeq Line From ActFvar Else Done = True
If Status() Then Done = True
Until Done Do
Convert " " To @FM In Line
If Line[1,1] = "P" Then
Found = True
If SearchFile # "" And SearchFile # Line<6> Then Found = False
If SearchJobid # "" And SearchJobid # Line<4> Then Found = False
If SearchUser # "" And SearchUser # Line<5> Then Found = False
If Found Then
NewLine<1> = Line<4>
NewLine<2> = Line<5>
NewLine<3> = Line<6>
NewLine<4> = Line<9>
NewLine<5> = Line<3>
OutData<-1> = Lower(NewLine)
End
End
Repeat
* Ensure that the resultant output does not exceed 16K. This
* is due to an RPC restriction on 16 bit client apps.
If Len(OutData) > 16384 Then
Temp = Right(OutData,16384)
Num = Len(Temp) - index(Temp,@FM,1)
OutData = Right(Temp,Num)
End
End Else
Error = EADM.CANTOPEN
End
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* SpoolPrinterDets - Returns information about jobs on a specific
* printer from the usplog file
* Unix only
*
* Input: Printer name
* Output: Form name
* Status byte
* Job details: Job Id
* Job description
* Owner
* Priority
* Form
* Size
* Copies
* Status
* Delay
* Default form flag
**********************************************************************
SpoolPrinterDets:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
PrinterName = Params<1>
* First check that the spooler is running
GoSub CheckSpooler
If Error # 0 Then
Return
End
GoSub SpStatuses
GoSub GetSpoolDetails
If Error <> False Then
Return
End
* Get printer details (form and status byte)
Dc = Dcount(PrinterList,@fm)
For I = 1 To Dc
If PrinterList<I,1> = PrinterName Then
Temp = Raise(PrinterList<I>)
OutData<1> = Temp<2> ; * Form name
OutData<2> = Temp<5> ; * Status byte
End
Next
* Now get job details
For I = 1 To NoJobs
Line = Raise(JobList<I>)
PrinterNo = PrintJobIndex<I>
If PrinterIndex<PrinterNo> = PrinterName Then
NewLine = Line<USPJ.JOBID>
NewLine<2> = Line<USPJ.BANNER>
UserNo = Line<USPJ.OWNER>
GoSub GetUserName
If UserName <> "" Then
NewLine<3> = UserName
End Else
NewLine<3> = Line<USPJ.OWNER>
End
NewLine<4> = Line<USPJ.PRIORITY>
NewLine<5> = Line<USPJ.FORM>
NewLine<6> = Line<USPJ.SIZE>
NewLine<7> = Line<USPJ.COPIES>
NewLine<8> = SpStatuses<Line<USPJ.STATUS>>
If Line<USPJ.HOLD> = 1 Then
If Line<USPJ.BEENPRINTED> = 1 Then
NewLine<8> := "&"
End Else
NewLine<8> := "*"
End
End
UspDelay = Line<USPJ.TIMER>
GoSub GetDelayTime
If Hours > 0 Or Mins > 0 Then
NewLine<9> = Hours : ":" : Mins
End Else
NewLine<9> = ""
End
NewLine<10> = ( Line<USPJ.FORM> <> PrinterList<PrinterNo,USPP.FORM> )
OutData<-1> = Lower(NewLine)
End
Next
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* SpoolSuspend - Suspend a printer
* Unix only
*
* Input: Printer name
* Output: NONE
**********************************************************************
SpoolSuspend:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
GoSub CheckSpooler
If Error # 0 Then
Return
End
ExLine = USA.PATH:" -b -p ":Params
Gosub ShellCommand
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* StartDeadLocking - Starts the dead lock process
*
* Input: Deadlock process start settings
* Output: Return Code
**********************************************************************
StartDeadLocking:
ReturnCode = 0
Error = ReturnCode
OutData = ""
* Load client values.
timer = Params<1>
res.strategy = Params<3>
log.directory = Trim(Params<5>)
ExLine = ""
LockOptions = "-t " : timer : " -r " : res.strategy : " -l " : log.directory:OS.SEP:"uvdlockd.log"
if OS.TYPE = "MSWIN" then
ExLine = UVHOMEBIN:"uvdlockd.exe ":LockOptions
ExLine = UVHOMEBIN:"uvbootd ":ExLine
end else
ExLine = UVHOMEBIN:"uvdlockd ":LockOptions
end
Gosub ShellCommand
Return
************************************************************************
* StartSpooler - Starts the spooler daemon using the script
* held in the uv.rc file
* Unix only
*
* Input: NONE
* Output: Output from usd script
************************************************************************
StartSpooler:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
If SPOOL.DIR = "" Then
Error = EADM.NOSPOOLDIR
Return
End
ExLine = Convert(@FM, ";", USD.SCRIPT)
Gosub ShellCommand
OutData = Out
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* StopDeadlocking - Stops the dead lock process
*
* Input: None
* Output: Return Code
**********************************************************************
StopDeadLocking:
Error = 0
OutData = ""
ExLine = ""
* Issue the stop command
ExLine:= UVHOMEBIN:"uvdlockd -stop"
Gosub ShellCommand
Return
************************************************************************
* StopSpooler - Stops the spooler daemon
* Unix only
*
* Input: NONE
* Output: NONE
************************************************************************
StopSpooler:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
ExLine = USA.PATH : " -z"
GoSub ShellCommand
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* TapeTest - Run the tape test program on a DT or DC
* device type
* NOTE: for NT, Rewind path & no-rewind path
* will be the same
*
* Input: Rewind path, no-rewind path,
* block size, device type
* Output: Block size, backup command, restore
* command, RW mode pos, Close on Read,
* Multiple read, account transfer block
* size
**********************************************************************
TapeTest:
RewindPath = Params<1>
NoRewindPath = Params<2>
TestSize = Params<3>
TapeType = Params<4>
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
* Check the device paths are valid (can't do this on NT as tape
* devices aren't files
OpenSeq RewindPath To TempFvar Then
CloseSeq TempFvar
End
Else
Error = EADM.BADREWIND
Return
End
OpenSeq NoRewindPath To TempFvar Then
CloseSeq TempFvar
End
Else
Error = EADM.BADNOREWIND
Return
End
End
************************
* OS specific code end *
************************
If BULL Then TestSize = 1024
If (TestSize = "" Or TestSize = 0) Then TestSize = 512
ExLine = "tapetest " : RewindPath : " " : NoRewindPath : " " : TestSize
GoSub UvCommand
Flds = Count(Out, @FM)
Success = Out<Flds>[1,10]
If Success = "SUCCESSFUL" Then
If TapeType = "DC" Then
If BULL Then
OutData<1> = 1024
OutData<7> = 1024
End
Else
OutData<1> = 512
OutData<7> = 512
End
End
Else
OutData<7> = 16384
End
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
OutData<2> = "find $file -print | cpio -ocvB > $tape"
OutData<3> = "cpio -icvBdum $file < $tape"
End Else
OutData<2> = ""
OutData<3> = ""
End
************************
* OS specific code end *
************************
OutData<4> = Field(Out, "^", 2)
OutData<5> = Field(Out, "^", 4)
OutData<6> = Field(Out, "^", 6)
End
Else
Error = EADM.TAPETESTFAILED
OutData = Out
End
Return
******************************************************************************
* UniVerseBrowse - Like a normal Browse, but instead of browsing the
* OS file system, it browses the uniVerse account/file
* system. The first argument indicates what kind of
* browse (account or file):
* 1 means return all the local files in the account;
* 2 means return all the records in the file.
*
* Input: Key
* Account name to browse
* File name to browse (only if Key = 2)
* Output: List of files or records
******************************************************************************
UniVerseBrowse:
Done = False
BrowseType = Params<1>
AccountName = Params<2>
If BrowseType = 1 then
Write "Q" : @FM : AccountName : @FM : "VOC" : @FM : "D_VOC" On VOC, "BROWSEPTR"
ExLine = "SSELECT BROWSEPTR WITH F1 LIKE F..."
ExLine := " AND F2 UNLIKE ...":OS.SEP:"..."
**************************
* OS specific code start *
**************************
* Checking for / on NT as this is still a valid separator in UniVerse files.
If OS.TYPE # "UNIX" Then
ExLine := " AND F2 UNLIKE .../..."
End
************************
* OS specific code end *
************************
Gosub TCLCommand
Loop
ReadNext Id From SList Else Done = True
Until Done Do
OutData<-1> = Id
Repeat
End Else
FileName = Params<3>
Write "Q" : @FM : AccountName : @FM : FileName : @FM : "D_VOC" On VOC, "BROWSEPTR"
Open "BROWSEPTR" Then
SSelect
ReadList OutData Then Error = False
Close
End
End
Delete VOC, "BROWSEPTR"
Return
***********************************************************************
* Unused - Returns a "Bad Call" error
*
* Input: NONE
* Output: NONE
***********************************************************************
Unused:
Error = EADM.BADCALL
Return
**********************************************************************
* UpdateDataSourceEntry - Updates a data source entry
*
* Input: Data Source Name
* Output: None
**********************************************************************
UpdateDataSourceEntry:
ReturnCode = 0
pos =0
DataSource = Params<1>
* Find the specified entry and update the details.
Locate DataSource In DataSourceArray Setting pos Then
DataSourceDetails<pos,2> = Params<2>
DataSourceDetails<pos,3> = Params<3>
DataSourceDetails<pos,4> = Params<4>
DataSourceDetails<pos,5> = Params<5>
* Write the details to the file. The Global Error will be set
* by this function and then sent back by this subroutine, with
* any errors on the write
Error = 0
Gosub WriteDataSources
End Else
ReturnCode = EADM.NOENTRY
End
Error = ReturnCode
Return
**********************************************************************
* UpdateUserInfoDetails - Writes the login account details for
* a specified user
*
* Input: An array of details for a user
* Output: NONE
**********************************************************************
UpdateUserInfoDetails:
Ok = 0
Error = 0
New = Params<1>
Domains = Params<4>
Domain = ""
DomainAccount = ""
LocalMachines = Params<5>
LocalMachine = ""
LocalAccount = ""
Rec = ""
UserInfo = ""
UserId = Params<2>
UserDesc = Params<3>
Lp = 1
OutData = ""
If DEBUGGING Then
LogText = "UserId :" : UserId
GoSub WriteDbg
End
* Open the UV.LOGINS file
Open '', "UV.LOGINS" To UvLoginsFvar Then
If New Then
Readv Rec From UvLoginsFvar, UserId, 0 Then
Error = EADM.ALREADYEXISTS
Close UvLoginsFvar
Goto Exit.UpdateUserInfoDetails
End
End
* fill in the user description, if any
Rec<5> = UserDesc
* loop pairing up all the domains and their corresponding accounts
Rec<1> = ""
Rec<3> = ""
If DEBUGGING Then
LogText = "Domains :" : Domains
GoSub WriteDbg
End
Loop
Remove Domain From Domains Setting Ok
If DEBUGGING Then
LogText = "Domain :" : Domain
GoSub WriteDbg
End
If Domain Then
If Ok = 4 Then
Remove DomainAccount From Domains Setting Ok
End Else
DomainAccount = ""
End
* Build the return data array
Rec<1, Lp> = Domain
Rec<3, Lp> = DomainAccount
Lp +=1
End
While Ok Do
Repeat
* reset the Lp counter as we'll reuse it
Lp = 1
Rec<2> = ""
Rec<4> = ""
Loop
Remove LocalMachine From LocalMachines Setting Ok
If LocalMachine Then
If Ok = 4 Then
Remove LocalAccount From LocalMachines Setting Ok
End Else
LocalAccount = ""
End
* Build the return data array
Rec<2, Lp> = LocalMachine
Rec<4, Lp> = LocalAccount
Lp +=1
End
While Ok Do
Repeat
* Write the user details back to the UV.LOGINS file
Write Rec on UvLoginsFvar, UserId Else
Error = EADM.CANTWRITE
End
Close UvLoginsFvar
End Else
Error = EADM.CANTOPEN
End
Exit.UpdateUserInfoDetails:
Return
**********************************************************************
* UserList - Returns a list of users (unix only)
*
* Input: NONE
* Output: List of users
**********************************************************************
UserList:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
FileName = "/etc/passwd"
Gosub ReadSeqFile
If Error <> False Then
Error = EADM.NOPASSWD
Return
End
Dc = Dcount(NewText,@Fm)
For I = 1 To Dc
If NewText<I>[1,1] <> "+" Then
OutData<-1> = NewText<I>[":",1,1]
End
Next
End
************************
* OS specific code end *
************************
Return
************************************************************************
* Users - Returns user data for interactive and
* background UniVerse users
*
* Input: NONE
* Output: Interactive user data
* Pid, User name, Who, Port,
* Login time, Last command
* Background process data
* Pid, User name, Printer segment,
* Last command (unix)
* Or
* Pid, User name, Port, Printer
* segment, Last command (NT)
************************************************************************
Users:
Interactive = ""
Background = ""
ExLine = "PORT.STATUS INTERNAL"
Gosub TCLCommand
* PORT.STATUS can only be used by one person at a time
if index(Out,"PORT.STATUS is currently being run",1) Then
Error = EADM.INUSE
End
* First line of output contains user counts
NumInteractive = Out<1,2>
NumBackground = Out<1,3>
IntStart = 2 ; * Start line for interactive users
BckStart = IntStart + NumInteractive
* Interactive users first
If NumInteractive > 0 Then
For IntIndex = IntStart To IntStart + NumInteractive - 1
Line = Trim(Out<IntIndex>)
**************************
* OS specific code start *
**************************
If OS.TYPE # "UNIX" Then
* PORT.STATUS does not display 'Who' (ie. user number) on
* NT. It is the same as the Pid, so insert it in the line
Ins Trim(Out<IntIndex, 1>) Before Line<1, 3>
End
************************
* OS specific code end *
************************
* Insert a blank value into the line for Last Logged In time.
* This will be filled in by cross-referencing to LISTU output
Ins "" Before Line<1,5>
Interactive<-1> = Line
Next IntIndex
End
* Now do background users
If NumBackground > 0 Then
For BckIndex = BckStart To BckStart + NumBackground - 1
Line = Trim(Out<BckIndex>)
**************************
* OS specific code start *
**************************
If OS.TYPE # "UNIX" Then
* We can show the user number for phantoms on NT, do this
* so that background processes can be logged off using MASTER
Ins Trim(Out<BckIndex, 1>) Before Line<1, 3>
End
************************
* OS specific code end *
************************
Background<-1> = Line
Next BckIndex
End
ExLine = "LISTU"
Gosub TCLCommand
Text = Out
Dc = Dcount(Text,@fm)
Dc2 = Dcount(Interactive,@fm)
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
* Use tty to cross-reference output from LISTU to get login times
* for interactive users. Extract login date/time by trimming to
* get rid of excess spaces and extracting the 3rd, 4th & 5th items
* to try and avoid problems with different formats of this output
* (eg. IBM outputs extra data after the date time)
For I = 1 To Dc2
Tty = Trim(Interactive<I,4>)
For J = 1 to Dc
Line = Trim(Text<J>)
UnixTTY = Line[" ",2,1]
TTYPaths = Count(UnixTTY,"/")
If Tty["/",Dcount(Tty,"/") - TTYPaths,TTYPaths+1] = UnixTTY Then
Line = Trim(Line)
Interactive<I,5> = Trim(Line[" ", 3, 3])
End
Next J
Next I
End Else
* Use Pid to cross-reference output from LISTU to get login times
* and portname for interactive users - this is more
* reliable for portname than PORT.STATUS as the latter gives
* "Unavailable" for the current process. Because user names
* can have spaces in them, access the portname and date/time
* from the end of the line
For I = 1 To Dc2
Pid = Trim(Interactive<I,1>)
For J = 1 To Dc
Line = Text<J>
UserNo = Trim(Line[14,7])
If UserNo = Pid Then
Line = Trim(Line)
NumSp = Count(Line, " ")
Interactive<I,4> = Trim(Line[" ", NumSp - 2, 1])
Interactive<I,5> = Trim(Line[" ", NumSp - 1, 3])
End
Next J
Next I
End
************************
* OS specific code end *
************************
OutData = Lower(Interactive) : @fm : Lower(Background)
Return
**********************************************************************
* ViewInfoFile - Read one of the transaction logging info files
*
* If the file is larger than 16K then the last 16K is returned and an
* error of EADM.FILETOLARGE is set.
*
* Input: Key 0 - logging info
* 1 - checkpoint info
* 2 - rollforward info
* Output: Contents of file
*
**********************************************************************
ViewInfoFile:
Key = Params<1>
* Get log directory and add the name of the info file to the path
InfoFile = ""
RECIO(InfoFile, RECIO$PATH)
InfoFile := OS.SEP
Begin Case
Case Key = 0
InfoFile := "uvlogd.info"
Case Key = 1
InfoFile := "uvchkd.info"
Case Key = 2
InfoFile := "uvrolf.info"
Case 1
InfoFile := "uvlogd.info"
End Case
* Open file and read contents. If file does not exist, don't do anything
* as the client expects an empty buffer if there is no file
OpenSeq InfoFile To InfoFvar Then
NewText = ""
* In case the file is huge, seek to the end and go back 16k
* bytes.
Seek InfoFvar, -16384, 2
Then
* Seek has succeded, therefore return a flag to indicate that
* the file has been truncated.
Error = EADM.FILETOLARGE
End
Else
* Seek failed has file will not be truncated.
Error = 0
End
Done = False
Loop
ReadSeq Line From InfoFvar Else Done = True
Until Done or Status() Do
NewText<-1> = Line
Repeat
CloseSeq InfoFvar
OutData = Change(NewText, @FM, CRLF)
End
Return
**********************************************************************
* WriteDataSources - Writes the data sources to the config file
*
* Input: None
* Output: None
**********************************************************************
WriteDataSources:
OutLine = ""
config.file = ""
Element = 0
Finish = 0
Total = 0
Ct = 0
ElementsArray = @FM:"DBMSTYPE = ":@FM:"network = ":@FM:"service = ":@FM:"host = "
* Open the uvodbc config file in the UniVerse home account
config.file = UVHOME : OS.SEP : "uvodbc.config"
OpenSeq config.file To FConfig.file Then
* Write the pre data to the file.
Total = Dcount(PreDataSources, @FM)
For Ct = 1 to Total
WriteSeq PreDataSources<Ct> On FConfig.file Else
Error = EADM.CANTWRITE
End
Next Ct
* Put a blank line in
WriteSeq "" On FConfig.file Else
Error = EADM.CANTWRITE
End
* Write the data source data to the config file
Total = DCount(DataSourceArray,@FM)
For Ct = 1 to Total
OutLine = "<":DataSourceArray<Ct>:">"
WriteSeq OutLine On FConfig.file Then
Element = 2
Finish = 0
loop
* If the database type is ODBC we do not write out any other data
If DataSourceDetails<Ct,Element> = "ODBC" Then
Finish = 1
End
WriteSeq ElementsArray<Element>: DataSourceDetails<Ct,Element> On FConfig.file Else
Error = EADM.CANTWRITE
End
Element +=1
Until Element > 5 Or Finish
Repeat
* Put a blank between each entry
WriteSeq "" On FConfig.file Else
Error = EADM.CANTWRITE
End
End Else
Error = EADM.CANTWRITE
End
Next Ct
* Write the post data to the config file
Total = DCount(PostDataSources, @FM)
If Total Then
For Ct = 1 to Total
WriteSeq PostDataSources<Ct> On FConfig.file Else
Error = EADM.CANTWRITE
End
Next Ct
End
* Truncate the rest of the file.
WeofSeq FConfig.file
CloseSeq FConfig.file
End Else
Error = EADM.NOFILE
End
Return
***********************************************************************
* U T I L I T Y R O U T I N E S
* ============= ===============
***********************************************************************
**********************************************************************
* AccPerms - Unix only
**********************************************************************
AccPerms:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Read AccRec From UVACCOUNT, Params<1> Else
Error = EADM.NOACCOUNT
Return
End
ThePath = AccRec<11>
Permissions = Params<2>
If Num(Permissions) Then
SetPerms = Permissions
End
Else
SetPerms = '000'
For I = 1 to 3
Temp = Permissions[(I*3)-2,3]
if Temp[1,1] = "r" Then SetPerms[I,1] = SetPerms[I,1] + 4
if Temp[2,1] = "w" Then SetPerms[I,1] = SetPerms[I,1] + 2
if Temp[3,1] = "x" Then SetPerms[I,1] = SetPerms[I,1] + 1
Next I
End
ExLine = 'find ':ThePath:' -exec chmod ':SetPerms:' {} \;'
GoSub ShellCommand
End
************************
* OS specific code end *
************************
Return
***********************************************************************
* CheckPathName
***********************************************************************
CheckPathName:
PathOk = True
If Not(Convert("; *&[]`$^","",PathName) = PathName ) Then
PathOk = False
End
Return
************************************************************************
* CheckSpooler - check to see if the spooler daemon is running
* Do this using usd -V.
* Unix only
************************************************************************
CheckSpooler:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
ExLine = USD.PATH:" -V"
GoSub ShellCommand
If Not (Index(Out, "active!", 1)) Then
Error = EADM.NOSPOOLER
End
End Else
Error = EADM.NOSPOOLER
End
************************
* OS specific code end *
************************
Return
************************************************************************
* CheckUserGone
************************************************************************
CheckUserGone:
sleep 1
CallSub = True
Gosub Users
CallSub = False
Found = False
For I = 1 To Dc
If Params = Out<I,1> Then
Found = I
End
Next
If Found = False Then
Out = ''
Return
End
If Out<I,5> = "Unavailable" Then
Found = False
End
Return
**********************************************************************
* Chown !C! - Unix only
**********************************************************************
Chown:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Path = Params<1>
Owner = Params<2>
Group = Params<3>
PathName= Path
GoSub CheckPathName
If PathOk = True Then
ExLine = "find ":Path:" -exec chown ":Owner:" {} \;"
GoSub ShellCommand
If Group <> "" Then
ExLine = "find ":Path:" -exec chgrp ":Group:" {} \;"
GoSub ShellCommand
End
End
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* ChownAcc !C! - Unix only
**********************************************************************
ChownAcc:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
AccountName = Params<1>
Read AccRec From UVACCOUNT, AccountName Else
Error = EADM.NOACCOUNT
Return
End
Params<1> = AccRec<11>
PathName = Params<1>
GoSub CheckPathName
If PathOk = True Then
GoSub Chown
End
End
************************
* OS specific code end *
************************
Return
**********************************************************************
* CleanUser
**********************************************************************
CleanUser:
Params<1> = UserId
Gosub KillUserLock
GoSub IPCRMAll
Return
***********************************************************************
* CloseFileFixFile
***********************************************************************
CloseFileFixFile:
* Close the file
CALL.ARGS(1,1) = FILEFIX.CLOSE ; * Close the File
CALL.ARGS(1,2) = UVRPC.INT
If RPC.CALL(FileFixConId, " ", 1, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
Error = RES.ARGS(1,1)
* Remapp error codes to match admin codes.
End Else
Error = Status() - 80000
End
Return
**********************************************************************
* ConvertPermissions - Expects: Perms to contain a "rwx---r-x"
* format string
* Unix only
**********************************************************************
ConvertPermissions:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
PermissionNum = '000'
For I = 1 to 3
Temp = Perms[(I*3)-2,3]
if Temp[1,1] = "r" Then PermissionNum[I,1] = PermissionNum[I,1] + 4
if Temp[2,1] = "w" Then PermissionNum[I,1] = PermissionNum[I,1] + 2
if Temp[3,1] = "x" Then PermissionNum[I,1] = PermissionNum[I,1] + 1
Next I
End
************************
* OS specific code end *
************************
Return
***********************************************************************
* EndFileFixServer
***********************************************************************
EndFileFixServer:
* Check to see if the connet is already running
If FileFixOpen NE 0 Then
* Close the connection to the service
FileFixConId = RPC.DISCONNECT(FileFixConId)
FileFixOpen = 0
End
Return
************************************************************************
* ExtractRestoreLabelField - Tries to match a line of output from
* uvrestore with the message text that produced
* it, and extract the value into the OutData
* dynamic array
*
* Inputs: Params Input data containing uvrestore output
* OutField Field number in Outdata for the result
* Msg Message number of text to be searched for
* Output: LineNo Line number in uvrestore output
************************************************************************
ExtractRestoreLabelField:
MsgText = UVREADMSG(Msg, "")
If Len(MsgText) = 0 Then
Return
End
Loop
While MsgText[1, 1] = @FM Do
Del MsgText<1>
Repeat
Check.String = TrimB(Field(MsgText, ":", 1))
Num.Fields = DCount(Params, @FM)
LineNo = 0
I = 1
Loop
While (LineNo = 0) And (I <= Num.Fields) Do
If Params<I>[1, Len(Check.String)] = Check.String Then
LineNo = I
OutData<OutField> = TrimF(Field(Params<LineNo>, ":", 2, 999))
End
I += 1
Repeat
Return
************************************************************************
* FindAccountName - Tries to match an account path to an account
* name.
*
* Before calling, the Accounts array and AccountNum
* variable need to have been set up and the
* pathname to be matched must be in the variable
* "AccountPath"
*
* If a match is found, the account name will be
* put into the "AccountName" variable. If no match
* is found this will be empty.
************************************************************************
FindAccountName:
AccountName = ""
For I = 1 To NumAccounts
If AccountPath = Accounts(I, 2) Then
AccountName = Accounts(I, 1)
Goto ExitFindAccountName
End
Next I
ExitFindAccountName:
Return
************************************************************************
* GetActLogPath - Finds the full path of the activity log file
* and puts it in ActLogFile
* Unix only
************************************************************************
GetActLogPath:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Temp1 = ""
Temp2 = ""
ActLogName = "act.log"
Call *SP.GET.UVRC.B(Temp1, Temp2)
ActLogDir = Temp1<3>
If ActLogDir = SPOOL.DIR Then
ActLogFile = ActLogDir : "/" : ActLogName
End Else
OpenPath ActLogDir To TmpFvar Then
ActLogFile = ActLogDir : "/" : ActLogName
End Else ; * check prev dir
If ActLogDir[Len(ActLogDir)] = "/" Then
ActLogDir = ActLogDir[1, Len(ActLogDir) - 1]
End
Levels = Count(ActLogDir, "/")
TmpPath = ActLogDir[1, Index(ActLogDir, "/", Levels)]
OpenPath TmpPath To TmpFvar Else
Error = EADM.CANTOPEN
Return
End
ActLogFile = ActLogDir[Index(ActLogDir, "/", Levels), 99]
End
Close TmpFvar
End
End
************************
* OS specific code end *
************************
Return
*********************************************************************
* GetDelayTime - Returns the defer time of a print job in
* hours & minutes relative to the current time
* If there is no defer time set, or we have
* gone past the defer time, hours and minutes
* will be set to 0
* Unix only
*
* Input: UspDelay (delay from usplog file)
* Output: Hours
* Mins
*
* If there is a time delay on a print job, it is held in the usplog
* in internal time and we have to convert it. The value held in
* usplog is the delay time as an absolute value which is: number of
* seconds from 00:00:00 GMT Jan 1st, 1970.
* To work out the actual delay, system(99) is used to get the time
* in the same format as the usplog file. Note, system(99) returns the
* value from the 'C' time() function. Using this actual time a delay
* time can be calculated.
*
***********************************************************************
GetDelayTime:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Hours = 0
Mins = 0
If UspDelay > 0 Then
CurrentTime = system(99)
Delay = UspDelay - CurrentTime
If Delay > 0 Then
Hours = Int(Delay/3600)
Tmp = Mod(Delay, 3600)
Mins = Int(Tmp/60)
End
End
End
************************
* OS specific code end *
************************
Return
************************************************************************
* GetErrLogPath - Finds the full path of the Error log file
* and puts it in ErrLogFile
* Unix only
************************************************************************
GetErrLogPath:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Temp1 = ""
Temp2 = ""
ErrLogName = "err.log"
Call *SP.GET.UVRC.B(Temp1, Temp2)
ErrLogDir = Temp1<2>
If ErrLogDir = SPOOL.DIR Then
ErrLogFile = ErrLogDir : "/" : ErrLogName
End Else
OpenPath ErrLogDir To TmpFvar Then
ErrLogFile = ErrLogDir : "/" : ErrLogName
End Else ; * check prev dir
If ErrLogDir[Len(ErrLogDir)] = "/" Then
ErrLogDir = ErrLogDir[1, Len(ErrLogDir) - 1]
End
Levels = Count(ErrLogDir, "/")
TmpPath = ErrLogDir[1, Index(ErrLogDir, "/", Levels)]
OpenPath TmpPath To TmpFvar Else
Error = EADM.CANTOPEN
Return
End
ErrLogFile = ErrLogDir[Index(ErrLogDir, "/", Levels), 99]
End
Close TmpFvar
End
End
************************
* OS specific code end *
************************
Return
********************************************************************
* GetPrinter - Read device details from sp.config file
* (unix only). DevRec will be empty if device
* definition is not found in sp.config
*
* Input: DevName
* Output: DevRec
********************************************************************
GetPrinter:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Found = False
Fin = False
SpConfigPath = SPOOL.DIR : "/sp.config"
OpenSeq SpConfigPath To FL Then
Loop
Until Fin Or Found Do
ReadSeq Line From FL Else Fin = True
If Line[" ", 1, 1] = DevName Then
Found = True
End
Repeat
CloseSeq FL
End
If Found Then
Convert " " To @fm In Line
* NOTES: Field 1 is description, which we will have to get
* from the &DEVICE& entry
* Field 3 is not used for printers
* Field 4 is device type and will always be "P"
DevRec<2> = Line<2> ; * Printer path
DevRec<4> = "P" ; * Device type
* First, do some initialisation for those fields which have
* a default if they're not mentioned in the sp.config line
DevRec<8> = 1 ; * No flow control
DevRec<9> = 1 ; * Printer enabled
DevRec<10> = 1 ; * Queueing enabled
DevRec<11> = 11 ; * Baud rate of 9600
DevRec<12> = 1 ; * Parity None
DevRec<13> = 1 ; * CR mode None
DevRec<14> = 2 ; * Tab expansion off
DevRec<15> = 1 ; * No formfeed delay
DevRec<16> = 1 ; * No linefeed delay
DevRec<17> = 8 ; * Wordlength 8
* Now parse the sp.config line
NumValues = Count(Line, @fm) + 1
For I = 3 To NumValues
Begin Case
Case Upcase(Line<I>) = "LOCKFILE" ; * LOCKFILE <path>
* LockFiles - can have up to 2 lockfiles in the
* lockfiles field, any more go in the options field
If DevRec<5> = "" Then
DevRec<5> = Line<I + 1>
End Else
If DevRec<5,2> = "" Then
DevRec<5,2> = Line<I + 1>
End Else
DevRec<18> := "LOCKFILE " : Line<I + 1> : " "
End
End
I += 1 ; * skip next value, already used
Case Upcase(Line<I>) = "DRIVER" ; * DRIVER <path>
DevRec<6> = Line<I + 1>
I += 1 ; * skip next value, already used
Case Upcase(Line<I>) = "FORMS" ; * FORMS <formname>
DevRec<7> = Line<I + 1>
I += 1 ; * skip next value, already used
Case Upcase(Line<I>) = "DTR"
* Can be one of two things, "DTR OFF XON OFF" or "DTR ON"
* These represent the first two possibilities for flow
* control (field 8). Make sure we skip the appropriate
* number of values after processing it
If Upcase(Line<I + 1>) = "OFF" Then
DevRec<8> = 1
I += 3 ; * skip next 3 values: "OFF XON OFF"
End Else
DevRec<8> = 2
I += 1 ; * skip next value: "ON"
End
Case Upcase(Line<I>) = "XOFF"
* Can be either "XOFF STARTANY ON" or "XOFF STARTANY OFF"
* These represent the final two possibilities for flow
* control (field 8). Again, make sure we skip the correct
* number of values
If Upcase(Line<I + 2>) = "ON" Then
DevRec<8> = 3
End Else
DevRec<8> = 4
End
I += 2
Case Upcase(Line<I>) = "NOPRINT" ; * disable printing
DevRec<9> = 2
Case Upcase(Line<I>) = "NOQUEUE" ; * disable queueing
DevRec<10> = 2
Case Upcase(Line<I>) = "BAUD" ; * BAUD <baud rate>
* We require an index into the baud rates array, rather
* than the baud rate itself
Find Line<I + 1> In baud.array Setting Fm Then
DevRec<11> = Fm
End
I += 1 ; * skip next value, already used
Case Upcase(Line<I>) = "PARITY" ; * PARITY NONE/EVEN/ODD
* We require an number representing the parity, rather
* than the text string
Find Line<I + 1> In parity.array Setting Fm Then
DevRec<12> = Fm
End
I += 1 ; * skip next value, already used
Case Upcase(Line<I>) = "CRMODE"
* CRMODE is only present if CR conversion is required
* We need a number representing the conversion required,
* rather than the text string
Find Line<I + 1> In cr.array Setting Fm Then
DevRec<13> = Fm
End
I += 1 ; * skip next value, already used
Case Upcase(Line<I>) = "TABS" ; * TABS ON/OFF
If Upcase(Line<I + 1>) = "ON" Then
DevRec<14> = 1
End Else
DevRec<14> = 2
End
I += 1 ; * skip next value, already used
Case Upcase(Line<I>) = "FFDELAY" ; * FFDELAY <index>
DevRec<15> = Line<I + 1>
I += 1 ; * skip next value, already used
Case Upcase(Line<I>) = "LFDELAY" ; * LFDELAY <index>
* Index used for LF delay is one less than the index we
* need, so add one to it
DevRec<16> = Line<I + 1> + 1
I += 1 ; * skip next value, already used
Case Upcase(Line<I>) = "DATABITS" ; * DATABITS <value>
DevRec<17> = Line<I + 1>
I += 1 ; * skip next value, already used
Case Upcase(Line<I>) = "MAPNAME" Or Upcase(Line<I>) = "MAP"
DevRec<19> = Line<I + 1>
I += 1
Case 1 ; * anything else goes into "Options"
DevRec<18> := Line<I> : " "
End Case
Next I
End ; * of processing printer definition in sp.config file
End
************************
* OS specific code end *
************************
Return
********************************************************************
* GetSpoolDetails - Unix only
********************************************************************
* Get the spooler details from the usplog file
* This builds two arrays; the first holds printer details
* and the second the details for each job
* The indexing allows other spooler commands to locate things
* a little more quickly; these are
* PrinterList = Array of printer details
* PrinterIndex = list of printer names
* JobList = Array of job details
* JobIndex = list of job numbers
* JobPrintIndex= 2-d index of printers and the job entry numbers
* in the job list associated with them
* PrintJobIndex= List of printer numbers associated with each job
*
* A mask is used to tell ProcessUspLine which fields in the line
* are delimeted by char(255) (mask = 1) and which are delimeted by
* a space (mask = 0)
********************************************************************
GetSpoolDetails:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
If USPLOG.PATH = "" Then
Error = EADM.NOUSPLOGPATH
Return
End
OpenSeq USPLOG.PATH To USPFL Else
Error = EADM.NOUSPLOG
Return
End
PrinterList = ""
JobList = ""
PrinterIndex = ''
JobIndex = ''
JobPrintIndex = ''
PrintJobIndex = ''
NoPrinters = 0
NoJobs = 0
Done = False
Loop
ReadSeq Line From USPFL Else Done = True
If Line[1,1] = "z" Then Done = True
If Status() Then Done = True
Until Done Do
First = Line[1,1]
Begin Case
Case First = "P"
Mask = "11110"
GoSub ProcessUspLine
NoPrinters += 1
PrinterList<NoPrinters>= Lower(NewLine)
PrinterIndex<NoPrinters> = NewLine<1>
CurrentPrinter = NewLine<1>
Case First = "p" ; * hangover from ADG code
Mask = "11110"
GoSub ProcessUspLine
PrinterList<-1>= Lower(NewLine)
PrinterIndex<-1> = NewLine<1>
Case (First = "J") Or (First = "M") ; * print job or mapped print job
Mask = "000000000000111100000110"
GoSub ProcessUspLine
ReadSeq Line From USPFL Else Done = True
If Line[1,1] <> "F" Then
Error = EADM.BADUSPLOG
Return
End
NewLine<USPJ.JOBNAME> = Line[Char(255),1,1][2,HUGE]
NoJobs += 1
JobList<NoJobs> = Lower(NewLine)
JobIndex<NoJobs> = NewLine<2>
JobPrintIndex<NoPrinters,-1> = NoJobs
PrintJobIndex<NoJobs> = NoPrinters
End Case
Repeat
CloseSeq USPFL
End
************************
* OS specific code end *
************************
Return
***********************************************************************
* GetUserName - Unix only
***********************************************************************
GetUserName:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
UserName = ""
UserFound = False
OpenSeq '/etc/passwd' To FL Then
Loop
ReadSeq UserLine From FL Then
If UserLine[":",3,1] = UserNo Then
UserFound = True
UserName = UserLine[":",1,1]
End
End Else UserFound = True
Until UserFound = True
Repeat
CloseSeq FL
End
End
************************
* OS specific code end *
************************
Return
************************************************************************
* InitSpooler - initialises the spooler variables held in
* named common
* Unix only
************************************************************************
InitSpooler:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
SpoolData = ""
Call *SP.GET.UVRC.B(SpoolData, USD.SCRIPT)
SPOOL.DIR = SpoolData<1>
USPLOG.PATH = SPOOL.DIR : "/usplog"
USA.PATH = UVHOMEBIN: "usa"
USM.PATH = UVHOMEBIN: "usm"
USD.PATH = UVHOMEBIN: "usd"
End
************************
* OS specific code end *
************************
Return
***********************************************************************
* IPCRMALL !C!
***********************************************************************
IPCRMAll:
If LINUX then
ExLine = "ipcs -m"
End Else
ExLine = "ipcs -mo"
End
GoSub ShellCommand
Keys = ""
Dc = Dcount(Out,@fm)
for I =1 To Dc
If Out<I>[" ",Dcount(Out<I>," "),1] = "0" Then
Line= Change(Trim(Out<I>)," ",@fm)
FindStr "0xaceb" In Line Setting Pos Then
Keys<-1> = Line<2>
End
End
Next
Dc = Dcount(Keys,@fm)
For I =1 To Dc
If LINUX then
ExLine = "ipcrm shm ":Keys<I>
End Else
ExLine = "ipcrm -m ":Keys<I>
End
Gosub ShellCommand
Next
Return
***********************************************************************
* KillUserLock
***********************************************************************
KillUserLock:
Read Rec From VOC, "UNLOCK" Else
Write Rec On VOC, "UNLOCK" ; * Not in all accounts
Return
End
ExLine = "unlock USER " :Params<1>:" ALL"
Gosub TCLCommand
Return
***********************************************************************
* LoadHeaderFileFixFile
***********************************************************************
LoadHeaderFileFixFile:
* Load the file header
CALL.ARGS(1,1) = FILEFIX.LOADUVHEADER ; * Load the header for the File
CALL.ARGS(1,2) = UVRPC.INT
If RPC.CALL(FileFixConId, " ", 1, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
Error = RES.ARGS(1,1)
* Remapp error codes to match admin codes.
End Else
Error = Status() - 80000
End
Return
***********************************************************************
* OpenFileFixFile
***********************************************************************
OpenFileFixFile:
* First Open the File
CALL.ARGS(1,1) = FILEFIX.OPEN ; * Open the File
CALL.ARGS(1,2) = UVRPC.INT
CALL.ARGS(2,1) = FixFilename
CALL.ARGS(2,2) = UVRPC.STRING
CALL.ARGS(3,1) = FixFilePath
CALL.ARGS(3,2) = UVRPC.STRING
If RPC.CALL(FileFixConId, " ", 3, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
Error = RES.ARGS(1,1)
End Else
Error = Status() - 80000
End
Return
********************************************************************
* RepBuildUVFileExceptionList - Builds list of file names
* that are to be excluded from the list of
* UniVerse files that can be published.
* Excluded files are, distributed files and
* their part files
*
* Input: None
* Output: File exception list
********************************************************************
RepBuildUVFileExceptionList:
OSAccountName = ""
AccountPath = ""
ExceptionList = ""
**************************************
*** Add special UniVerse files to ***
*** exception list. ***
**************************************
ExceptionList<-1> = "&COMO&"
ExceptionList<-1> = "&DEVICE&"
ExceptionList<-1> = "&ED&"
ExceptionList<-1> = "&HOLD&"
ExceptionList<-1> = "&MAP&"
ExceptionList<-1> = "&PARTFILES&"
ExceptionList<-1> = "&PH&"
ExceptionList<-1> = "&SAVEDLISTS&"
ExceptionList<-1> = "&TEMP&"
ExceptionList<-1> = "&UFD&"
ExceptionList<-1> = "&UNICODE.FILE&"
ExceptionList<-1> = "APP.PROGS"
ExceptionList<-1> = "APP.PROGS.O"
ExceptionList<-1> = "BASIC.HELP"
ExceptionList<-1> = "BCI.HELP"
ExceptionList<-1> = "BLTRS"
ExceptionList<-1> = "BP"
ExceptionList<-1> = "BP.O"
ExceptionList<-1> = "DICT.DICT"
ExceptionList<-1> = "DICT.PICK"
ExceptionList<-1> = "ERRMSG"
ExceptionList<-1> = "GLOBAL.CATDIR"
ExceptionList<-1> = "NEWACC"
ExceptionList<-1> = "NLS.BP.O"
ExceptionList<-1> = "NLS.CLIENT.LCS"
ExceptionList<-1> = "NLS.CLIENT.MAPS"
ExceptionList<-1> = "NLS.CS.ALPHAS"
ExceptionList<-1> = "NLS.CS.BLOCKS"
ExceptionList<-1> = "NLS.CS.CASES"
ExceptionList<-1> = "NLS.CS.DESCS"
ExceptionList<-1> = "NLS.CS.INSTALL"
ExceptionList<-1> = "NLS.CS.LISTING"
ExceptionList<-1> = "NLS.CS.TYPES"
ExceptionList<-1> = "NLS.LANG.INFO"
ExceptionList<-1> = "NLS.LC.ALL"
ExceptionList<-1> = "NLS.LC.COLLATE"
ExceptionList<-1> = "NLS.LC.CTYPE"
ExceptionList<-1> = "NLS.LC.INSTALL"
ExceptionList<-1> = "NLS.LC.LISTING"
ExceptionList<-1> = "NLS.LC.MONETARY"
ExceptionList<-1> = "NLS.LC.NUMERIC"
ExceptionList<-1> = "NLS.LC.TIME"
ExceptionList<-1> = "NLS.MAP.DESC"
ExceptionList<-1> = "NLS.MAP.INSTALL"
ExceptionList<-1> = "NLS.MAP.LISTING"
ExceptionList<-1> = "NLS.MAP.TABLES"
ExceptionList<-1> = "NLS.WT.LOOKUP"
ExceptionList<-1> = "NLS.WT.TABLES"
ExceptionList<-1> = "REVISE.DISCUSSIONS"
ExceptionList<-1> = "REVISE.PROCESSES"
ExceptionList<-1> = "SQL.HELP"
ExceptionList<-1> = "STAT.FILE"
ExceptionList<-1> = "SYS.HELP"
ExceptionList<-1> = "SYS.MESSAGE"
ExceptionList<-1> = "UNIVERSE.INCLUDE"
ExceptionList<-1> = "UNIVERSE.MENU.FILE"
ExceptionList<-1> = "UNIVERSE.STAT.FILE"
ExceptionList<-1> = "UNIVERSE.VOCLIB"
ExceptionList<-1> = "USER.HELP"
ExceptionList<-1> = "UV.ACCESS"
ExceptionList<-1> = "UV.ACCOUNT"
ExceptionList<-1> = "UV.FLAVOR"
ExceptionList<-1> = "UV.LOGINS"
ExceptionList<-1> = "UV.SAVEDLISTS"
ExceptionList<-1> = "UV.TRANS"
ExceptionList<-1> = "UV_ASSOC"
ExceptionList<-1> = "UV_COLUMNS"
ExceptionList<-1> = "UV_LOGS"
ExceptionList<-1> = "UV_SCHEMA"
ExceptionList<-1> = "UV_TABLES"
ExceptionList<-1> = "UV_UDRPUB"
ExceptionList<-1> = "UV_UDRSUB"
ExceptionList<-1> = "UV_UDRSYS"
ExceptionList<-1> = "UV_USERS"
ExceptionList<-1> = "UV_VIEWS"
If IsFullPath(AccountName) Then
AccountPath = AccountName
End Else
* Specific account name
ReadV AccountPath From UVACCOUNT, AccountName, 11 Else
Error = EADM.CANTREADPATH
Return
End
End
**************************************
*** List all the distributed files ***
**************************************
OSAccountName = AccountPath
Convert OS.SEP TO @FM IN OSAccountName
**************************
* OS specific code start *
**************************
* Checking for / on NT as this is still a valid separator in UniVerse files.
If OS.TYPE # "UNIX" Then
Convert "/" TO @FM IN OSAccountName
End
************************
* OS specific code end *
************************
OSAccountName = OSAccountName<DCount(OSAccountName,@FM)>
Open "","&PARTFILES&" To UvPartFvar Then
EXECUTE "SELECT &PARTFILES& WITH ACCOUNT = ":OSAccountName
Fin = False
Loop
Readnext Id Then
PartFile = Id
Convert OS.SEP TO @FM IN PartFile
**************************
* OS specific code start *
**************************
* Checking for / on NT as this is still a valid separator in UniVerse files.
If OS.TYPE # "UNIX" Then
Convert "/" TO @FM IN PartFile
End
************************
* OS specific code end *
************************
PartFile = PartFile<DCount(PartFile,@FM)>
Line = PartFile
ExceptionList<-1> = Line
End Else Fin = True
Until Fin
Repeat
Close UvPartFvar
End Else
Error = EADM.CANTOPEN
End
Return
********************************************************************
* RepDistFileAdminClear - Clears the flag for a specified file in
* &PARTFILES& so that the command DEFINE.DF
* can again be used on this file.
*
* Input: Account, File name, Dist File name
* Output: None
********************************************************************
RepDistFileAdminClear:
Open "","&PARTFILES&" To UvPartFvar Then
EXECUTE "SELECT &PARTFILES& WITH @ID LIKE ...":FileName:" AND WITH ACCTPATH EQ ":AccountPath:" AND WITH DISTFILE EQ ":MDName:" AND WITH PARTNUM NE 'Distributed'"
Readnext Id Then
Readu Rec From UvPartFvar, Id Then
Rec<7> = ""
Write Rec On UvPartFvar, Id Then
End Else
Error = EADM.CANTWRITE
End
End Else
Error = EADM.CANTREAD
End
End
Close UvPartFvar
End Else
Error = EADM.CANTOPEN
End
Return
********************************************************************
* RepDistFileAdminSet - Sets a flag for a specified file in
* &PARTFILES& so that the command DEFINE.DF
* can NOT be used on files that are marked
* for replication.
*
* Input: Account, File name, Dist File name
* Output: None
********************************************************************
RepDistFileAdminSet:
Open "","&PARTFILES&" To UvPartFvar Then
EXECUTE "SELECT &PARTFILES& WITH @ID LIKE ...":FileName:" AND WITH ACCTPATH EQ ":AccountPath:" AND WITH DISTFILE EQ ":MDName:" AND WITH PARTNUM NE 'Distributed'"
Readnext Id Then
Readu Rec From UvPartFvar, Id Then
Rec<7> = "R"
Write Rec On UvPartFvar, Id Then
End Else
Error = EADM.CANTWRITE
End
End Else
Error = EADM.CANTREAD
End
End
Close UvPartFvar
End Else
Error = EADM.CANTOPEN
End
Return
********************************************************************
* RepGetNextPublicationsKey - Gets the next available publication
* Key
*
* Input: None
* Output: PubKey
********************************************************************
RepGetNextPublicationsKey:
found = 0
rec = ""
nextkey = ""
Open "DICT" ,"UV_UDRPUB" To DictUvUdrPub.Fvar Then
Open "" ,"UV_UDRPUB" To UvUdrPub.Fvar Then
Readvu nextkey from DictUvUdrPub.Fvar, "&NEXT.AVAILABLE&", 2 Then
Loop
Readv rec from UvUdrPub.Fvar, nextkey, 0 Then
* It already exists add one and try again
nextkey +=1
If nextkey > 2147483646 Then
nextkey = 1
End
End Else
found = 1
PubKey = nextkey
nextkey +=1
If nextkey > 2147483646 Then
nextkey = 1
End
Writev nextkey On DictUvUdrPub.Fvar, "&NEXT.AVAILABLE&", 2 Else
Error = EADM.CANTWRITE
End
End
Until found Do
Repeat
End Else
Error = EADM.CANTREAD
End
Close UvUdrPub.Fvar
End Else
Error = EADM.CANTOPEN
End
Close DictUvUdrPub.Fvar
End Else
Error = EADM.CANTOPEN
End
Return
********************************************************************
* RepGetNextRepSystemKey - Gets the next available System Key
*
* Input: None
* Output: SysKey
********************************************************************
RepGetNextRepSystemKey:
found = 0
rec = ""
nextkey = ""
Open "DICT" ,"UV_UDRSYS" To DictUvUdrSys.Fvar Then
Open "" ,"UV_UDRSYS" To UvUdrSys.Fvar Then
Readvu nextkey from DictUvUdrSys.Fvar, "&NEXT.AVAILABLE&", 2 Then
Loop
Readv rec from UvUdrSys.Fvar, nextkey, 0 Then
* Its already exists add one and try again
nextkey +=1
If nextkey > 2147483646 Then
nextkey = 1
End
End Else
found = 1
SysKey = nextkey
nextkey +=1
If nextkey > 2147483646 Then
nextkey = 1
End
Writev nextkey On DictUvUdrSys.Fvar, "&NEXT.AVAILABLE&", 2 Else
Error = EADM.CANTWRITE
End
End
Until found Do
Repeat
End Else
Error = EADM.CANTREAD
End
Close UvUdrSys.Fvar
End Else
Error = EADM.CANTOPEN
End
Close DictUvUdrSys.Fvar
End Else
Error = EADM.CANTOPEN
End
Return
********************************************************************
* RepGetNextSubscriptionKey - Gets the next available subscription
* Key
*
* Input: None
* Output: SubKey
********************************************************************
RepGetNextSubscriptionKey:
found = 0
nextkey = ""
rec = ""
Open "DICT" ,"UV_UDRSUB" To DictUvUdrSub.Fvar Then
Open "" ,"UV_UDRSUB" To UvUdrSub.Fvar Then
Readvu nextkey from DictUvUdrSub.Fvar, "&NEXT.AVAILABLE&", 2 Then
Loop
Readv rec from UvUdrSub.Fvar, nextkey, 0 Then
* It already exists add one and try again
nextkey +=1
If nextkey > 2147483646 Then
nextkey = 1
End
End Else
found = 1
SubKey = nextkey
nextkey +=1
If nextkey > 2147483646 Then
nextkey = 1
End
Writev nextkey On DictUvUdrSub.Fvar, "&NEXT.AVAILABLE&", 2 Else
Error = EADM.CANTWRITE
End
End
Until found Do
Repeat
End Else
Error = EADM.CANTREAD
End
Close UvUdrSub.Fvar
End Else
Error = EADM.CANTOPEN
End
Close DictUvUdrSub.Fvar
End Else
Error = EADM.CANTOPEN
End
Return
********************************************************************
* RepPublishFileDType - Publishs dictionaries for general
* UniVerse file types including
* type 2-18, 25, and 30.
*
* Input: None
* Output: SubKey
********************************************************************
RepPublishFileDType:
PubRecord = "" ; * record buffer to be written to UV_UDRPUB
OSDictName = ""
FilePath = ""
DictPubKey = ""
DTypeFileName = ""
DTypePubType = ""
* determine if this is a dictionary for a Multi-level file or regular file
Open '', "UV_UDRPUB" To UvPubFvar Then
Readv DTypePubType From UvPubFvar, FileKeyForDictPub, 5 Then
If DTypePubType = "M" Then
DTypeFileName = MDName
End Else
DTypeFileName = FileName
End
End Else ; * FAILED - Readv DictPubKey
Error = EADM.BADFILE
End ; * END - Readv DictPubKey
Close UvPubFvar
End Else
Error = EADM.CANTOPEN
End
Openpath AccountPath:OS.SEP:"VOC" To UvVocFvar Then
Readv OSDictName From UvVocFvar, DTypeFileName, 3 Then
OSDictName = Trim(OSDictName)
If IsFullPath(OSDictName) Then
FilePath = OSDictName
End Else
FilePath = AccountPath:OS.SEP:OSDictName
End
End Else ; * FAILED - Readv OSDictName
Error = EADM.BADFILE
End ; * END - Readv OSDictName
Close UvVocFvar
End Else ; * FAILED - Open account VOC
Error = EADM.BADFILE
End ; * END - Open account VOC
If Not(Error) Then
Error = UDRgetheaderinfo(FilePath, Flag, Id)
If Not(Error) Then
If Flag = UDRNONE Then
Gosub RepGetNextPublicationsKey
If Not(Error) Then
PubRecord<1> = FileName
PubRecord<2> = Account
PubRecord<3> = Description
PubRecord<5> = PubType : @VM : DTypePubType
PubRecord<6> = AccessList
PubRecord<11> = FileKeyForDictPub
PubRecord<17> = MDName
PubRecord<18> = DictName
Open '', "UV_UDRPUB" To UvPubFvar Then
Write PubRecord To UvPubFvar, PubKey Then
Error = UDRsetheaderinfo(FilePath, UDRPUB, PubKey)
If Error Then
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.UDRINVALIDFILE
Case Error = -5
Error = EADM.BADFILEREV
End Case
End
ResultingPubKey = PubKey
* now we need to set the parent file flag.
Readv DictPubKey From UvPubFvar, FileKeyForDictPub, 11 Then
If DictPubKey <> 0 Then
Error = EADM.UDRINUSE
End
Writev PubKey To UvPubFvar, FileKeyForDictPub, 11 Else
Error = EADM.CANTWRITE
End
End Else ; * FAILED - Readv DictPubKey
Error = EADM.BADFILE
End ; * END - Readv DictPubKey
End Else
Error = EADM.CANTWRITE
End
Close UvPubFvar
End Else
Error = EADM.CANTOPEN
End
End
End Else
Error = EADM.UDRINUSE
End
End Else
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.UDRINVALIDFILE
Case Error = -5
Error = EADM.BADFILEREV
End Case
End
End ; * END of publishing file
Return
********************************************************************
* RepPublishFileFType - Publishs general UniVerse file type.
* Including type 2-18, 25, and 30
*
* Input: None
* Output: PubKey
********************************************************************
RepPublishFileFType:
PubRecord = "" ; * record buffer to be written to UV_UDRPUB
OSFileName = ""
FilePath = ""
Openpath AccountPath:OS.SEP:"VOC" To UvVocFvar Then
Readv OSFileName From UvVocFvar, FileName, 2 Then
OSFileName = Trim(OSFileName)
If IsFullPath(OSFileName) Then
FilePath = OSFileName
End Else
FilePath = AccountPath:OS.SEP:OSFileName
End
End Else ; * FAILED - Readv OSFileName
Error = EADM.BADFILE
End ; * END - Readv OSFileName
Close UvVocFvar
End Else ; * FAILED - Open account VOC
Error = EADM.BADFILE
End ; * END - Open account VOC
If Not(Error) Then
Error = UDRgetheaderinfo(FilePath, Flag, Id)
If Not(Error) Then
If Flag = UDRNONE Then
Gosub RepGetNextPublicationsKey
If Not(Error) Then
PubRecord<1> = FileName
PubRecord<2> = Account
PubRecord<3> = Description
PubRecord<5> = PubType
PubRecord<6> = AccessList
PubRecord<11> = "0"
PubRecord<17> = MDName
Open '', "UV_UDRPUB" To UvPubFvar Then
Write PubRecord To UvPubFvar, PubKey Then
Error = UDRsetheaderinfo(FilePath, UDRPUB, PubKey)
If Error Then
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.UDRINVALIDFILE
Case Error = -5
Error = EADM.BADFILEREV
End Case
End
If PubType = "MD" Then
Gosub RepDistFileAdminSet
End
ResultingPubKey = PubKey
End Else
Error = EADM.CANTWRITE
End
Close UvPubFvar
End Else
Error = EADM.CANTOPEN
End
End
End Else
Error = EADM.UDRINUSE
End
End Else
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.UDRINVALIDFILE
Case Error = -5
Error = EADM.BADFILEREV
End Case
End
End ; * END of publishing file
Return
********************************************************************
* RepPublishFileMType - Publishes Multi-level UniVerse files.
*
* Input: None
* Output: SubKey
********************************************************************
RepPublishFileMType:
PubRecord = "" ; * record buffer to be written to UV_UDRPUB
MPartNames = ""
MOSPartNames = ""
OSFileName = ""
FilePath = ""
Openpath AccountPath:OS.SEP:"VOC" To UvVocFvar Then
Readv MPartNames From UvVocFvar, MFileName, 7 Then
Find MPartName in MPartNames Setting Fmc, Vmc, Smc Then
Readv MOSPartNames From UvVocFvar, MFileName, 8 Then
Tmp = MOSPartNames<Fmc,Vmc>
If IsFullPath(Tmp) Then
FilePath = Tmp ; * use multi-part full os file name
End Else
FilePath = AccountPath:OS.SEP:MFileName:OS.SEP:Tmp ; * add multi-part os file name
End
End Else ; * FAILED - Readv MOSPartNames
Error = EADM.BADFILE
End
End Else
Error = EADM.BADFILE
End ; * END - Find multi-part file name
End Else ; * FAILED - Readv MPartNames
Error = EADM.BADFILE
End ; * END - Readv MPartNames
Close UvVocFvar
End Else ; * FAILED - Open account VOC
Error = EADM.BADFILE
End ; * END - Open account VOC
If Not(Error) Then
Error = UDRgetheaderinfo(FilePath, Flag, Id)
If Not(Error) Then
If Flag = UDRNONE Then
Gosub RepGetNextPublicationsKey
If Not(Error) Then
PubRecord<1> = MPartName
PubRecord<2> = Account
PubRecord<3> = Description
PubRecord<5> = PubType
PubRecord<6> = AccessList
PubRecord<11> = "0"
PubRecord<17> = MFileName
Open '', "UV_UDRPUB" To UvPubFvar Then
Write PubRecord To UvPubFvar, PubKey Then
Error = UDRsetheaderinfo(FilePath, UDRPUB, PubKey)
If Error Then
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.UDRINVALIDFILE
Case Error = -5
Error = EADM.BADFILEREV
End Case
End
ResultingPubKey = PubKey
End Else
Error = EADM.CANTWRITE
End
Close UvPubFvar
End Else
Error = EADM.CANTOPEN
End
End
End Else
Error = EADM.UDRINUSE
End
End Else
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.UDRINVALIDFILE
Case Error = -5
Error = EADM.BADFILEREV
End Case
End
End ; * END of publishing file
Return
********************************************************************
* RepPublishFileQType - Publishs UniVerse Q-Pointers.
*
* Input: None
* Output: SubKey
********************************************************************
RepPublishFileQType:
PubRecord = "" ; * record buffer to be written to UV_UDRPUB
QAccountName = ""
QAccountPath = ""
QFileName = ""
OSFileName = ""
FilePath = ""
TmpFlag = 0;
TmpPubKey = "";
Openpath AccountPath:OS.SEP:"VOC" To UvVocFvar Then
Readv QAccountName From UvVocFvar, FileName, 2 Then
Readv QFileName From UvVocFvar, FileName, 3 Then
Readv QAccountPath From UVACCOUNT, QAccountName, 11 Then
Openpath QAccountPath:OS.SEP:"VOC" To UvVocFvar2 Then
Readv OSFileName From UvVocFvar2, QFileName, 2 Then
If IsFullPath(OSFileName) Then
FilePath = OSFileName
End Else
FilePath = QAccountPath:OS.SEP:OSFileName
End
End Else ; * FAILED - Readv OSFileName
Error = EADM.BADFILE
End ; * END - Readv OSFileName
Close UvVocFvar2
End Else ; * FAILED - Open Q-pointer account VOC
Error = EADM.BADFILE
End ; * END - Open Q-pointer account VOC
End Else ; * FAILED - Readv QAccountPath
Error = EADM.BADFILE
End ; * END - Readv QAccountPath
End Else ; * FAILED - Readv QFileName
Error = EADM.BADFILE
End ; * END - Readv QFileName
End Else ; * FAILED - Readv QAccountName
Error = EADM.BADFILE
End ; * END - Readv QAccountName
Close UvVocFvar
End Else ; * FAILED - Open account VOC
Error = EADM.BADFILE
End ; * END - Open account VOC
If Not(Error) Then
Error = UDRgetheaderinfo(FilePath, Flag, Id)
If Not(Error) Then
TmpFlag = Flag
TmpPubKey = Id
If Flag = UDRNONE Then
Gosub RepGetNextPublicationsKey
If Not(Error) Then
PubRecord<1> = QFileName
PubRecord<2> = QAccountName
PubRecord<3> = "Published via a Q-Pointer"
PubRecord<5> = "F"
PubRecord<6> = AccessList
PubRecord<11> = "0"
PubRecord<17> = MDName
Open '', "UV_UDRPUB" To UvPubFvar Then
Write PubRecord To UvPubFvar, PubKey Then
Error = UDRsetheaderinfo(FilePath, UDRPUB, PubKey)
If Error Then
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.UDRINVALIDFILE
Case Error = -5
Error = EADM.BADFILEREV
End Case
End
TmpPubKey = PubKey
End Else
Error = EADM.CANTWRITE
End
Close UvPubFvar
End Else
Error = EADM.CANTOPEN
End
End
End
If (Not(Error) & TmpFlag NE UDRSUB) Then ; * publishing the file succeded, or file exists so now do q-pointer
Open '', "UV_UDRPUB" To UvPubFvar Then
Readu PubRecord From UvPubFvar, TmpPubKey Then
PubRecord<12,-1> = FileName
PubRecord<13,-1> = Account
PubRecord<14,-1> = Description
PubRecord<15,-1> = PubType
PubRecord<16,-1> = "0"
Write PubRecord To UvPubFvar, TmpPubKey Then
ResultingPubKey = TmpPubKey
End Else
Error = EADM.CANTWRITE
End
End Else ; * FAILED - Readu PubRecord
Error = EADM.CANTREAD
End
Close UvPubFvar
End Else
Error = EADM.CANTOPEN
End
End Else
If TmpFlag = UDRSUB Then
Error = EADM.UDRINUSE
End
End
End Else
Begin Case
Case Error = -1
Error = EADM.BADFUNCCALL
Case Error = -2
Error = EADM.BADFILE
Case Error = -3
Error = EADM.UDRINVALIDFILE
Case Error = -5
Error = EADM.BADFILEREV
End Case
End
End ; * END of publishing file
Return
***********************************************************************
* SetupFileFix
***********************************************************************
SetupFileFix:
* Setup the subsystem
CALL.ARGS(1,1) = FILEFIX.SETUP ; * Setup
CALL.ARGS(1,2) = UVRPC.INT
CALL.ARGS(2,1) = FileFixLevel
CALL.ARGS(2,2) = UVRPC.INT
CALL.ARGS(3,1) = FileFixFix
CALL.ARGS(3,2) = UVRPC.INT
CALL.ARGS(4,1) = FileFixErrorLevel
CALL.ARGS(4,2) = UVRPC.INT
If RPC.CALL(FileFixConId, " ", 4, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
Error = RES.ARGS(1,1)
End Else
Error = Status() - 80000
End
Return
***********************************************************************
* SetupLoggingFileFix
***********************************************************************
SetupLoggingFileFix:
* Setup the filefix logging subsystem
CALL.ARGS(1,1) = FILEFIX.SETUPLOGGING ; * Setup Logging
CALL.ARGS(1,2) = UVRPC.INT
CALL.ARGS(2,1) = FileFixLogging
CALL.ARGS(2,2) = UVRPC.INT
CALL.ARGS(3,1) = FileFixLoggingPath
CALL.ARGS(3,2) = UVRPC.STRING
CALL.ARGS(4,1) = FileFixOutput
CALL.ARGS(4,2) = UVRPC.INT
CALL.ARGS(5,1) = FileFixOutputPath
CALL.ARGS(5,2) = UVRPC.STRING
If RPC.CALL(FileFixConId, " ", 5, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
Error = RES.ARGS(1,1)
End Else
Error = Status() - 80000
End
Return
***********************************************************************
* ShutdownFileFix
***********************************************************************
ShutdownFileFix:
* Shutdown the subsystem
CALL.ARGS(1,1) = FILEFIX.SHUTDOWN ; * Shutdown
CALL.ARGS(1,2) = UVRPC.INT
If RPC.CALL(FileFixConId, " ", 1, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
Error = RES.ARGS(1,1)
End Else
Error = Status() - 80000
End
Return
***********************************************************************
* StartFileFixServer
***********************************************************************
StartFileFixServer:
* Check to see if its already open and do not open if it is.
If FileFixOpen = 0 Then
SystemName = "localhost"
SERVICE = FILEFIX.SERVICE
* Open the connection to the service
FileFixConId = RPC.CONNECT(SystemName, SERVICE)
If FileFixConId Then
FileFixOpen = 1
Error = 0
End Else
Error = Status() - 80000
End
End
Return
***********************************************************************
* Process usp line - Unix only
* Numbers are space delimited
* Strings are delimited with char(255) and a space - which is determined
* by the mask which has been set up for this field: mask value of 1
* denotes that the delimeter is char(255), mask value of 0 denotes
* that the delimeter is a space
***********************************************************************
ProcessUspLine:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
NewLine = ''
Line = Line[2,9999]
UspFields = Len(Mask)
For K = 1 To UspFields
If Mask[K,1] Then
Ix = Index(Line,Char(255),1)
NewLine<K> = Line[1,Ix-1]
Line = Line[Ix+2,HUGE]
End Else
NewLine<K> = Line[" ",1,1]
Line = Line[" ",2,HUGE]
End
Next
End
************************
* OS specific code end *
************************
Return
************************************************************************
* PutPrinter - Writes a printer definition to the sp.config
* file (unix only)
*
* Input: DevName
* DevRec
* Output: NONE
************************************************************************
PutPrinter:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
* First set up an sp.config format line for this printer
DevLine = DevName : " " : DevRec<2> ; * printer name & path
DevLine = DevName:" ":DevRec<2>
If DevRec<6> # "" Then
DevLine := " DRIVER ":DevRec<6>
End
If DevRec<7> # "" Then
DevLine := " FORMS ":DevRec<7>
End
Begin Case
Case DevRec<8> = 2
DevLine := " DTR ON"
Case DevRec<8> = 3
DevLine := " XOFF STARTANY ON"
Case DevRec<8> = 4
DevLine := " XOFF STARTANY OFF"
End Case
If DevRec<9> # 1 Then
DevLine := " NOPRINT"
End
If DevRec<10> # 1 Then
DevLine := " NOQUEUE"
End
If DevRec<11> # "" Then
DevLine := " BAUD " : baud.array<DevRec<11>>
End
If DevRec<12> # "" Then
DevLine := " PARITY " : parity.array<DevRec<12>>
End
If DevRec<13> > 1 Then ; * Mode 1 is no conversion
DevLine := " CRMODE " : cr.array<DevRec<13>>
End
If DevRec<14> Then
DevLine := " TABS ON"
End Else
DevLine := " TABS OFF"
End
If DevRec<15> # "" Then
DevLine := " FFDELAY " : DevRec<15>
End
If DevRec<16> # "" Then
DevLine := " LFDELAY " : DevRec<16> - 1
End
If DevRec<17> # "" Then
DevLine := " DATABITS " : DevRec<17>
End
If DevRec<5, 1> # "" Then
DevLine := " LOCKFILE " : DevRec<5, 1>
If DevRec<5, 2> # "" Then
DevLine := " LOCKFILE " : DevRec<5,2>
End
End
If DevRec<18> # "" Then
DevLine := " ":DevRec<18>
End
If DevRec<19> # "" Then
DevLine := " MAPNAME " : DevRec<19>
End
* Now write the definition line to the sp.config file
SpConfigPath = SPOOL.DIR : "/sp.config"
Config = ''
* Open the sp.config file. If it does not exist then create it.
OpenSeq SpConfigPath TO FL Else
Create FL Else
Error = EADM.NOSPCONFIG
Return
End
End
Found = False
Ct = 0
Loop
Ct += 1
ReadSeq Line From FL Else Line = ''
Until Status() Do
If Line[" ",1,1] = DevName Then
Found = Ct
End
Config<-1> = Line
Repeat
If Not(Found) Then Found = -1
Config<Found> = DevLine
* Write Config file back
Seek FL,0 Else Null
WeofSeq FL
Dc = Dcount(Config,@fm)
For I = 1 To Dc
WriteSeq Config<I> On FL Else Null
Next I
CloseSeq FL
* Now reset the spooler to ensure that usplog contains details
* for this new printer
ExLine = USA.PATH:" -r"
GoSub ShellCommand
End
************************
* OS specific code end *
************************
Return
************************************************************************
* ReadAndConvertHosts - Reads the /etc/hosts file and converts
* the contents into usable data
* Unix only
*
* The ETC.FVAR global must contain the
* open file variable for /etc.
*
* Sets up two arrays:
*
* OrigHosts - contains unmodified
* data from hosts file
* HostData - line feeds converted to
* field marks, comment and
* blank lines left unchanged,
* each host definition line
* contains:
* IPAddr @VM Name @SM Name....
************************************************************************
ReadAndConvertHosts:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
* Read hosts file - take a lock on the file so that no-one else
* can update it - this will be released when the user exits
* network services administration
Readu OrigHosts From ETC.FVAR, "hosts" Locked
Error = EADM.RECLOCKED
End Else
Error = EADM.CANTREAD
End
If Error = 0 Then
HostData = OrigHosts
Convert Char(10) To @fm In HostData
NumLines = DCount(HostData, @fm)
* Parse the /etc/hosts file. Any line starting with "#" is a comment
* line and can be ignored. Format of a host definition line is as
* follows:
*
* <ipc address> <host name> [<synonym host name>...] # <comment>
For Index = 1 To NumLines
If HostData<Index> # "" And HostData<Index>[1,1] # "#" Then
Line = Trim(HostData<Index>)
Pos = Index(Line, '#', 1)
If Pos Then Line = Line[1, Pos - 1]
Pos = Index(Line, ' ', 1)
HostData<Index> = Line[1, Pos - 1] : @vm : Convert(' ', @sm, Line[Pos + 1, Len(Line)])
End
Next I
End
End
************************
* OS specific code end *
************************
Return
************************************************************************
* ReadSeqFile
************************************************************************
ReadSeqFile:
$OPTIONS EXTRA.DELIM
OpenSeq FileName To FL Else
Error = EADM.NOFILE
Return
End
NewText = ''
Done = False
Loop
ReadSeq Line From FL Else Done = True
Until Done or Status() Do
NewText<-1> = Line
Repeat
If KeepFileOpen = False Then
CloseSeq FL
End
$OPTIONS -EXTRA.DELIM
Return
************************************************************************
* SetPort - Searches the services file for the
* port which requires changing, changes
* the value, and writes the file back.
* If there is no existing line for this
* port, adds a new line (and comment)
* to the services file. Assumes that the
* 'etc' file has been opened to ETC.FVAR.
*
* Input: PortNo - new port number
* PortString - search string
* PortComment - comment
************************************************************************
SetPort:
* Read the services file and search for PortString.
Readu Services From ETC.FVAR, "services" Locked
Error = EADM.RECLOCKED
End Else
Error = EADM.CANTREAD
End
If Error = 0 Then
Convert Char(10) To @fm In Services
FindStr PortString In Services Setting LineNo Then
* Port already has a definition. Find the port number and
* replace it
PortLine = Services<LineNo>
PortLineLen = Len(PortLine)
Pos = 1
Loop
Until PortLine[Pos,1] = " " Or PortLine[Pos,1] = Char(9) Or Pos > PortLineLen
Pos += 1
Repeat
Loop
While (PortLine[Pos,1] = " " Or PortLine[Pos,1] = Char(9)) And Pos < PortLineLen
Pos += 1
Repeat
NumLen = Index(PortLine[Pos, PortLineLen - Pos], '/', 1) - 1
* Now we've found the start position & length of the old port
* number, set up a new line by replacing the old port number
* with the new one
NewPortLine = PortLine[1, Pos - 1] : PortNo
NewPortLine := PortLine[Pos + NumLen, PortLineLen - Pos - NumLen + 1]
Services<LineNo> = NewPortLine
End Else
* No exisiting definition for this port, add one to the file
Services<-1> = PortString : Char(9) : Char(9) : PortNo : "/tcp"
Services<-1> := Char(9) : Char(9) : Char(9) : PortComment
End
* Write Services back to services file, maintaining lock
Convert @fm To Char(10) In Services
Writeu Services To ETC.FVAR, "services" Locked
Error = EADM.RECLOCKED
End Else
Error = EADM.CANTWRITE
End
End
Return
***********************************************************************
* ShellCommand
***********************************************************************
ShellCommand:
* Only add the quotes around the line on UNIX. On NT when using DOS /C
* there is no need for them. Also need to escape the & characters using
* ^& on NT and \& on UNIX.
back = 0
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
Command = OS.EXEC:" '"
If ExLine[LEN(ExLine)-1, 2] = "&&" Then
back = 1
ExLine = ExLine[1, Len(ExLine) -2]
End
For x = 1 to Len(ExLine)
if ExLine[x,1] = "&" Then
Command := "\&"
End Else
Command := ExLine[x,1]
End
Next
If back Then
Command := " &"
End
Command := "'"
End Else
Command = OS.EXEC:" "
For x = 1 to Len(ExLine)
if ExLine[x,1] = "&" Then
* If we have a '&&' this is the NT Command separator so
* don't convert.
if ExLine[x-1,4] = " && " then
Command := "&"
x += 1
End Else
Command := "^&"
End
End Else
Command := ExLine[x,1]
End
Next
End
************************
* OS specific code end *
************************
Execute Command, Out. > Out
Return
***********************************************************************
* SpStatuses - creates an array containing job statuses
* Unix only
***********************************************************************
SpStatuses:
**************************
* OS specific code start *
**************************
If OS.TYPE = "UNIX" Then
SpStatuses = "Wait"
SpStatuses<2> = "Hold"
SpStatuses<4> = "Active"
SpStatuses<8> = "Suspend"
SpStatuses<16> = "PHold"
End
************************
* OS specific code end *
************************
Return
***********************************************************************
* TCLCommand
***********************************************************************
TCLCommand:
Execute ExLine, Out. > Out, Select. > SList
Return
***********************************************************************
* UnloadHeaderFileFixFile
***********************************************************************
UnloadHeaderFileFixFile:
* Unload the file header
CALL.ARGS(1,1) = FILEFIX.UNLOADUVHEADER ; * Unload the header for the File
CALL.ARGS(1,2) = UVRPC.INT
If RPC.CALL(FileFixConId, " ", 1, MAT CALL.ARGS, RES.COUNT, MAT RES.ARGS) Then
Error = RES.ARGS(1,1)
* Remapp error codes to match admin codes.
End Else
Error = Status() - 80000
End
Return
***********************************************************************
* UvCommand
***********************************************************************
UvCommand:
ExLine = UVHOMEBIN:ExLine
Gosub ShellCommand
Return
**********************************************************************
* WriteSeqFile
**********************************************************************
WriteSeqFile:
If UnixFileOpen = False Then
OpenSeq FileName To FL Else
Create FL Else
Error = EADM.NOWRITEFILE
Return
End
End
End Else
Seek FL,0 Else
Error = EADM.SEEKERROR
Return
End
End
WEofSeq FL
Dc = Dcount(NewText,@fm)
For I =1 to Dc
WriteSeq NewText<I> On FL Else
Error = EADM.WRITEERROR
I = Dc
End
Next
CloseSeq FL
Return
**********************************************************************
* WriteDbg - log debug text to file
* Expects debug text in LogText variable
**********************************************************************
WriteDbg:
WriteSeq Change(LogText, @fm, Char(10)) On DEBUGFL Else Null
Seek DEBUGFL, 0, 2 Else Null
Return