12885 lines
414 KiB
Plaintext
12885 lines
414 KiB
Plaintext
|
*******************************************************************************
|
||
|
*
|
||
|
* 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
|