******************************************************************************* * * 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[1,1] <> "+" Then If NewText[":",6,1] = AccPath Then HomeDirFlag = 1 UserList<-1> = NewText[":",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 = Params<1> DataSourceDetails = Params<2> DataSourceDetails = Params<3> DataSourceDetails = Params<4> DataSourceDetails = 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 Del DataSourceDetails 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 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 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 = 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 = Field(line[2,999],">",1) End Begin Case Case line[1,8] = "DBMSTYPE" DataSourceDetails = Trim(Field(line,"=",2)) Case line[1,7] = "network" DataSourceDetails = Trim(Field(line,"=",2)) Case line[1,7] = "service" DataSourceDetails = Trim(Field(line,"=",2)) Case line[1,4] = "host" DataSourceDetails = 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 = 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 OutData<2> = DataSourceDetails OutData<3> = DataSourceDetails OutData<4> = DataSourceDetails 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 Del OutData 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 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, 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 : @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 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 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 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, @sm) If HostData # "" Then OutData<-1> = HostData : @vm : HostData 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 ; * 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 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 For I = 1 To IdNum If IdArray # (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) 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 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[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 * if input flag is true, or * 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[1,1] <> "+" Then If ShowGID = True Then OutData<-1> =NewText[":",3,1]:" ":NewText[":",1,1] End Else OutData<-1> = NewText[":",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) OutData = Line OutData<2> = Line OutData<3> = Line OutData<4> = Line OutData<5> = Line OutData<6> = Line OutData<7> = Line OutData<8> = Line UspDelay = Line 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 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 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, "D2") StartTime = Oconv(Rec, "MTS") FullDate = Oconv(Rec, "D2") FullTime = Oconv(Rec, "MTS") Size = Rec LogStatus = Rec Offset = Rec 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) 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 <> "" then File = Trim(Out) 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 <> "" Then OutData<-1> = "D":Trim(Out) 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 <> "" Then OutData<-1> = "F":Trim(Out) 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[1, 1] = " " Then OutData<6> = OutData<6> : TrimB(TrimF(Params)) 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 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 * Account Name * Pub State * 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 : " SAVING UNIQUE ACCOUNT" ReadNext Id Then OutData = 1 Else OutData = 0 * check for sub state EXECUTE "SELECT UV_UDRSUB WITH ACCOUNT EQ " : OutData : " SAVING UNIQUE ACCOUNT" ReadNext Id Then OutData = 1 Else OutData = 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 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 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 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="logdir=":replogdir End If found.replogsize = 0 Then line.no += 1 rec = "logsize=":replogsize End If found.repcurrentlog = 0 Then line.no += 1 rec = "logcurrent=":repcurrentlog End If found.repoldestlog = 0 Then line.no += 1 rec = "logoldest=":repoldestlog End If found.repboot = 0 Then line.no += 1 rec = "logboot=":repboot End If found.repsubdebug = 0 Then line.no += 1 rec = "debug=":repsubdebug End End Else If found.sublogdir = 0 Then line.no += 1 rec = "repdir=":sublogdir End If found.subboot = 0 Then line.no += 1 rec = "repboot=":subboot End If found.repsubdebug = 0 Then line.no += 1 rec = "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 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="start=":startval End If found.timer = 0 Then line.no += 1 rec = "timer=":timer End If found.resolve = 0 Then line.no += 1 rec = "res=":res.strategy End If found.logdir = 0 Then line.no += 1 rec = "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 = 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 If HostData = "" Then Del HostData Del OrigHosts 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 If HostData = "" Then Del HostData Del OrigHosts End End Find NewIPAddr In HostData Setting i, j, k Then HostData = NewNodeName End Else HostData<-1> = NewIPAddr : @vm : NewNodeName End End Else ; * Nodename change only Find NodeName In HostData Setting i, j, k Then HostData = 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[1, 1] = "#" Then WriteHosts = OrigHosts End Else Pos = Index(OrigHosts, '#', 1) If Pos Then WriteHosts := OrigHosts[Pos, Len(OrigHosts)] 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 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 ParamValue = Params Occur = 1 Loop FindStr ParamName In NewText,Occur Setting Pos Else Pos = -1 End Until Pos < 0 Or NewText[1,1] # COMMENT$CHAR Do Occur += 1 Repeat If Pos < 0 Then NewText<-1> = ParamName:" ":ParamValue End Else NewText = 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, @VM, 1) Fil = Field(ShmData, @VM, 2) Prog = Field(ShmData, @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 - Delete item from shared * memory * 2 - Add item to shared memory * 3 - 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 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, " ") Pos = Index(ProgLines, " ", NumSpaces) Path = ProgLines[Pos + 1, Len(ProgLines) - 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 = PrinterName Then Temp = Raise(PrinterList) 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) PrinterNo = PrintJobIndex If PrinterIndex = PrinterName Then NewLine = Line NewLine<2> = Line UserNo = Line GoSub GetUserName If UserName <> "" Then NewLine<3> = UserName End Else NewLine<3> = Line End NewLine<4> = Line NewLine<5> = Line NewLine<6> = Line NewLine<7> = Line NewLine<8> = SpStatuses> If Line = 1 Then If Line = 1 Then NewLine<8> := "&" End Else NewLine<8> := "*" End End UspDelay = Line GoSub GetDelayTime If Hours > 0 Or Mins > 0 Then NewLine<9> = Hours : ":" : Mins End Else NewLine<9> = "" End NewLine<10> = ( Line <> PrinterList ) 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[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 = Params<2> DataSourceDetails = Params<3> DataSourceDetails = Params<4> DataSourceDetails = 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[1,1] <> "+" Then OutData<-1> = NewText[":",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) ************************** * 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) 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) ************************** * 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) 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) For J = 1 to Dc Line = Trim(Text) UnixTTY = Line[" ",2,1] TTYPaths = Count(UnixTTY,"/") If Tty["/",Dcount(Tty,"/") - TTYPaths,TTYPaths+1] = UnixTTY Then Line = Trim(Line) Interactive = 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) For J = 1 To Dc Line = Text UserNo = Trim(Line[14,7]) If UserNo = Pid Then Line = Trim(Line) NumSp = Count(Line, " ") Interactive = Trim(Line[" ", NumSp - 2, 1]) Interactive = 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 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:">" 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 = "ODBC" Then Finish = 1 End WriteSeq ElementsArray: DataSourceDetails 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 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 Then Found = I End Next If Found = False Then Out = '' Return End If Out = "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[1, Len(Check.String)] = Check.String Then LineNo = I OutData = TrimF(Field(Params, ":", 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) = "LOCKFILE" ; * LOCKFILE * 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 End Else If DevRec<5,2> = "" Then DevRec<5,2> = Line End Else DevRec<18> := "LOCKFILE " : Line : " " End End I += 1 ; * skip next value, already used Case Upcase(Line) = "DRIVER" ; * DRIVER DevRec<6> = Line I += 1 ; * skip next value, already used Case Upcase(Line) = "FORMS" ; * FORMS DevRec<7> = Line I += 1 ; * skip next value, already used Case Upcase(Line) = "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) = "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) = "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) = "ON" Then DevRec<8> = 3 End Else DevRec<8> = 4 End I += 2 Case Upcase(Line) = "NOPRINT" ; * disable printing DevRec<9> = 2 Case Upcase(Line) = "NOQUEUE" ; * disable queueing DevRec<10> = 2 Case Upcase(Line) = "BAUD" ; * BAUD * We require an index into the baud rates array, rather * than the baud rate itself Find Line In baud.array Setting Fm Then DevRec<11> = Fm End I += 1 ; * skip next value, already used Case Upcase(Line) = "PARITY" ; * PARITY NONE/EVEN/ODD * We require an number representing the parity, rather * than the text string Find Line In parity.array Setting Fm Then DevRec<12> = Fm End I += 1 ; * skip next value, already used Case Upcase(Line) = "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 In cr.array Setting Fm Then DevRec<13> = Fm End I += 1 ; * skip next value, already used Case Upcase(Line) = "TABS" ; * TABS ON/OFF If Upcase(Line) = "ON" Then DevRec<14> = 1 End Else DevRec<14> = 2 End I += 1 ; * skip next value, already used Case Upcase(Line) = "FFDELAY" ; * FFDELAY DevRec<15> = Line I += 1 ; * skip next value, already used Case Upcase(Line) = "LFDELAY" ; * LFDELAY * Index used for LF delay is one less than the index we * need, so add one to it DevRec<16> = Line + 1 I += 1 ; * skip next value, already used Case Upcase(Line) = "DATABITS" ; * DATABITS DevRec<17> = Line I += 1 ; * skip next value, already used Case Upcase(Line) = "MAPNAME" Or Upcase(Line) = "MAP" DevRec<19> = Line I += 1 Case 1 ; * anything else goes into "Options" DevRec<18> := Line : " " 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= Lower(NewLine) PrinterIndex = 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 = Line[Char(255),1,1][2,HUGE] NoJobs += 1 JobList = Lower(NewLine) JobIndex = NewLine<2> JobPrintIndex = NoJobs PrintJobIndex = 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[" ",Dcount(Out," "),1] = "0" Then Line= Change(Trim(Out)," ",@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 End Else ExLine = "ipcrm -m ":Keys 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 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 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 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 = Line[1,Ix-1] Line = Line[Ix+2,HUGE] End Else NewLine = 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> End If DevRec<12> # "" Then DevLine := " PARITY " : parity.array> End If DevRec<13> > 1 Then ; * Mode 1 is no conversion DevLine := " CRMODE " : cr.array> 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 = DevLine * Write Config file back Seek FL,0 Else Null WeofSeq FL Dc = Dcount(Config,@fm) For I = 1 To Dc WriteSeq Config 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: * * [...] # For Index = 1 To NumLines If HostData # "" And HostData[1,1] # "#" Then Line = Trim(HostData) Pos = Index(Line, '#', 1) If Pos Then Line = Line[1, Pos - 1] Pos = Index(Line, ' ', 1) HostData = 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 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 = 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 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