home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
rxneterr.zip
/
neterr.cmd
< prev
next >
Wrap
OS/2 REXX Batch file
|
1999-02-02
|
47KB
|
1,041 lines
/* program neterr genned 99/02/02 16:25:09 */
Signal Prolog; /* standard entry */
/*-------------------------------------------------------------------*
* <C> 1996, Wolfram Fassbender, WRZ FUBerlin,
* WoFa at CCMailer.WiWiss.FU-Berlin.DE
*
* History:
* 96/12/06 - original version by courtesy of WoFa96
* 97/04/15 - rewritten to fit wofa's REXX programming standard
*
.* - read and clear LAN error logs from each server
.* Where:
.* no parms
.* Options:
.* Clear - clear log (default: only read)
.* Verbose - chat heavily
.* Silent - silent running (default)
.* LOCal - local error file only (default: all servers)
.* Logging - write chat to yyddd.LOG (default: no log)
.* Nirvana - exit off into nirvana (default: back to caller)
.* Returns:
.* 0 - all done
.* 1 - Help request (give some hints)
.* 2 - REXX Syntax error
.* 3 - User interrupted
.* Notes:
.* NONE
*-------------------------------------------------------------------*/
FINI: /* my very own closeup */
Arg ErrCode
Return ErrCode;
/*-------------------------------------------------------------------*/
USEROPT: /* set my own option */
Parse Arg OptName,OptValue
Optname = Translate(Space(OptName,0));
If OptName = '' Then Return UserIni();
Select
When Abbrev('CLEAR',OptName,1) Then ClearLog = True;
When Abbrev('LOCAL',OptName,3) Then LocalLog = True;
OtherWise Nop;
End; /* select */
Return 0;
/*-------------------------------------------------------------------*/
USERINI: /* init my own options */
LocalLog = True;
ClearLog = True;
Return 0;
/*-------------------------------------------------------------------*/
MAIN: /* main entry */
Arg ErrCode
/* insert code here */
Call FilesIni;
Iam = Netini();
Call Info 'I am 'Iam
Parse Var Iam id'@'hostname'.'Domainname' via 'DCName
ErrTxtBuffer = FileRead(LocalPath'\neterr.tab');
if LocalLog,
Then Return EpiLog(ReadError());
Parse Value lstserver() with NofServers';'ServerList;
Call Info 'found 'NofServers' server in 'domainname
Do While serverlist <> ''
parse value Space(serverlist) with server' 'serverlist
call info 'found server 'server
Call ReadError Server
end;
Return Epilog(ErrCode); /* return to caller */
/*-------------------------------------------------------------------*/
CLOSELOG: /* clear error log */
Arg SrvName
if \ClearLog Then Return 1; /* not requested */
if NetMisc(640,'\\'SrvName,Server'.LOG') <> 0,
Then Return Info('cannot clear error log on Server 'SrvName)
Return Info('error log cleared on server 'SrvName)
/*-------------------------------------------------------------------*/
ISERROR: /* strip error text from NETERR.TAB buffer */
Arg ErrNo
ErrIX = Pos('NET'ErrNo':',ErrTxtBuffer);
if ErrIX = 0 Then Return ''
ErrEnd = Pos('0d0a'x,ErrTxtBuffer,ErrIX);
Return SubStr(ErrTxtBuffer,ErrIX,ErrEnd-ErrIX);
/*-------------------------------------------------------------------*/
NETCODE: procedure expose ErrInfo. /* fake var errcode */
Arg ec
Return ErrInfo.ec.ErrCode
/*-------------------------------------------------------------------*/
READERROR: /* read error log from server */
Arg srvname
if srvname = '',
Then srvname = Hostname; /* set local error log */
ErrLog = LocalPath'\'srvname'.ERR';
Call SysFileDelete ErrLog;
Call LineOut ErrLog,'Error Log 'srvname' from 'Date(o)' 'Time();
errinfo.openflags = 0; /* read oldest record 1st from the beginning */
errinfo.buffer = 64000 /* read a 64k Buffer */
if NetMisc(650,'errinfo','\\'srvname) <> 0,
Then Return Info('cannot read error log from server 'srvname)
Call LineOut ErrLog,'found 'Errinfo.count' entries on' srvname
if Errinfo.count = 0,
Then Return Info('no records available on server 'srvname)
Call Info 'found 'ErrInfo.count' entries on 'SrvName
Call Info 'writing 'ErrLog;
Do I = 1 to ErrInfo.count
Call Info 'found error ('i') (Error 'NetCode(i)') 'Translate(Errinfo.i.time,' ','0a'x)'0d'x;
Call LineOut ErrLog,'Time 'Translate(Errinfo.i.time' 'ErrInfo.i.component,' ','0a'x);
Call LineOut ErrLog,'Error 'NetCode(i)': 'IsError(NetCode(i));
if ErrInfo.i.nstrings <> 0,
Then Do;
Do j = 1 to ErrInfo.i.nstrings
Call LineOut ErrLog,'Text 'j' 'Errinfo.i.string.j
End; /* do j */
End; /* if nstrings */
Call LineOut ErrLog,'Raw Data 'Errinfo.i.rawlength
if ErrInfo.i.rawlength <> 0,
Then Do;
ErrNo = x2d(c2x(SubStr(ErrInfo.i.Rawdata,2,1)||SubStr(ErrInfo.i.Rawdata,1,1)));
ErrData = IsError(ErrNo);
if ErrData = '',
Then Do;
Call LineOut ErrLog,'Raw Errors 'c2x(ErrInfo.i.Rawdata)
Call LineOut ErrLog,'Raw Errors 'ErrInfo.i.Rawdata
End;
Else Call LineOut ErrLog,ErrData
End; /* if rawdata */
End; /* do i */
Call Stream ErrLog,'c','close';
Call Info; /* force new line */
Call Info 'error log written to 'ErrLog
Call CloseLog SrvName
Return 0;
/*-------------------------------------------------------------------*/
/* NET */
/* FILES */
/*-------------------------------------------------------------------*
m* MODULE net
* TAG
* FILES
*
* <C> Wolfram Fassbender, wofa@wiwiss.fu-berlin.de
* History:
* 1996/06/06 - 1.0 initial release
* 1996/08/08 - 1.1 added some functions
* 1996/08/10 - 1.1 added INIUSER function
* 1997/04/10 - 2.0 introduced NET.! prefix
* added LAN.DATE conversion function
* 1998/01/15 - 2.2 added DOMAIN MAP handler in module init, wofa98
* 1998/04/22 - 2.3 modifiy INIUSER PROFILE.xx handler, wofa98
* 1998/09/26 - 2.4 modify GETUSER (include PW retrieval from DC), wofa98
* 1998/10/08 - 2.5 ignore default group USERS in ADDUSER, wofa98
* return ID:PW correctly from NET.GETPW, wofa98
c*
c* Tag Fields as follows
c* - AC.yyddd julian date of ACcount entry
c* - AF.flags Account Flags
c* - AR.rights Access Rights
c* - AS.asia ASia tag
c* - FN.name,name FullName (cc:mail name)
c* - FS.homedef home File Set
c* - GN.groupid GroupName
c* - GL.id id NET.!grouplist
c* - HD.domain Home Domain name
c* - LL.yyddd julian date of Last Login entry
c* - OP.privilege user's Operation Privilege
c* - PO.postoffice cc:mail Post Office name
c* - PW.password lan & cc:mail PassWord
c* - RN.res-name Ressource Name
c* - RP.res-path Ressource Path/Queue
c* - RT.res-type Ressource Type (files, serial, printer)
c* - RU.res-users Ressource max Users
c* - SN.serverid ServerName
c* - UL.userlist userlist (in a group)
c* - UN.userid lan UserName
c* - WS.nnnn Working Storage of homefileset
c*
c* userentry record
c* - UN.;FN.;OP.;PW.;AF.;LL.;PO.;AC.;AS.;HD.;FS.;WS.;GL.;
c*
c* groupentry record
c* - GN.;FN.;FS.;PO.;AC.;WS.;FS.;WS.;UL.;
c*
c* serverentry record
c* - SN.;FN.;
c*
c* ressourceentry record
c* - RN.;FN.;SN.;RT.;RP.;RU.;
c*
c* filentry record
c* - RN.;RP.;UN.;
c*
c* Implementation Notes
c* - need LXRXUT.DLL (from IBM LAN SERVER 3.0 and up)
*-------------------------------------------------------------------*/
NETINI: /* initialize module net */
/* init lib */
Call RxFuncAdd Loadlsrxutfuncs,lsrxut,loadlsrxutfuncs
Call LoadLSRXutfuncs;
Call TagIni;
Call FilesIni
Call Net.Domains;
Return ID(); /* identify my very own environment */
/*-------------------------------------------------------------------*/
ADDUSER: /* add a new user entry */
Parse Arg NET.!userentry;
/* all set what I need ? */
if GetTag('UN.',NET.!userentry) = '', /* ? User Name */
Then Return 1; /* need User Name */
if GetTag('FN.',NET.!userentry) = '', /* ? Full Name */
Then Return 2; /* need Full name */
if GetTag('PW.',NET.!userentry) = '', /* ? Pass Word */
Then Return 3; /* need Pass Word */
/* use defaults, if not set */
if GetTag('AF.',NET.!userentry) = '', /* ? Account Flags */
Then NET.!userentry = SetTag('AF.','S',NET.!userentry);
if GetTag('OP.',NET.!userentry) = '', /* ? Op Privilege */
Then NET.!userentry = SetTag('OP.','U',NET.!userentry);
if GetTag('WS.',NET.!userentry) = '', /* ? Working Storage */
Then NET.!userentry = SetTag('WS.','0',NET.!userentry);
/* setup entry record */
NET.!usr.Name = GetTag('UN.',NET.!userentry)
NET.!usr.password = ''; /* initially blank password */
NET.!usr.priv = NET.Privilege(GetTag('OP.',NET.!userentry));
NET.!usr.home_dir = GetTag('FS.',NET.!userentry)
NET.!usr.comment = Net.Comment(NET.!userentry);
NET.!usr.flags = GetTag('AF.',NET.!userentry);
NET.!usr.auth_flags = '';
NET.!usr.usr_comment = GetTag('FN.',NET.!userentry);
NET.!usr.script_path = '';
NET.!usr.max_storage = GetTag('WS.',NET.!userentry);
NET.!usr.logon_server = '\\*';
/* use ADDUSER2 */
NET.!ErrCode = NetAdd(282,NET.!Usr.,NET.!dcid);
if NET.!ErrCode <> 0 Then Return NET.!ErrCode; /* cannot add user */
Call ModUser 'GL.',NET.!userentry; /* setup group list */
Call ModUser 'PW.',NET.!userentry; /* setup password */
Call IniUser NET.!userentry; /* initialize DCDB */
drop NET.!Usr.
Return 0; /* user added */
/*-------------------------------------------------------------------*/
ADDGROUP: /* add a new group */
Parse Arg NET.!groupentry
if NET.!groupentry = '' Then Return 1; /* need group name */
Parse Value Space(NET.!groupentry) with NET.!grp.Name';'NET.!grp.comment
ErrCode = NetAdd(70,grp,NET.!dcid);
Drop NET.!grp.
Return ErrCode
/*-------------------------------------------------------------------*/
CHKUSER: /* validate an user entry */
Arg NET.!userentry; /* assume that PW tag is set */
if NetMisc(500,NET.!usr,GetTag('UN.',NET.!userentry),GetTag('PW.',NET.!userentry),NET.!dcid) <> 0,
Then Return False; /* cannot use LAN or wrong PW */
if NET.!usr.code <> 0 Then Return False; /* pw invalid */
drop NET.!usr.
Return True; /* pw ok */
/*-------------------------------------------------------------------*/
DOMAIN: /* retrieve domain from Domain.map */
Parse Arg dcname .
Return RecGet(NET.!DomainMap,'SN.'dcname);
/*-------------------------------------------------------------------*/
NETFIN: /* finalize module net */
Drop NET.
Return 0; /* identify my very own environment */
/*-------------------------------------------------------------------*/
DELFILE: /* close open net file on server */
Arg NET.!filename,NET.!serverentry
if NET.filename = '' Then Return 1; /* need file id */
NET.!srvname = GetTag('SN.',NET.!serverentry);
if NET.srvname = '' Then Return 2; /* need srv name */
if SubStr(NET.!srvname,1,1) <> '\',
Then NET.!srvname = '\\'NET.!srvname;
if NetDelete(220,NET.!file,NET.!srvname,NET.!filename) <> 0,
Then Return 3; /* cannot close file */
Return 0; /* file closed */
/*-------------------------------------------------------------------*/
DELUSER: /* delete an user entry from LAN */
Parse Arg NET.!userentry;
Return NetDelete(280,NET.!dcid,GetTag('UN.',NET.!userentry));
/*-------------------------------------------------------------------*/
GETACCESS: /* get access of a resource */
Return Space(AccessEntry);
/*-------------------------------------------------------------------*/
GETALIAS: /* get an alias entry */
Arg NET.!aliname
if NetGetInfo(20,NET.!als,NET.!dcid,NET.!aliName) <> 0,
Then Return ''; /* error condition */
NET.!AliasEntry = 'RN.'NET.!als.name';'
NET.!AliasEntry = NET.!AliasEntry'FN.'NET.!als.remark';'
NET.!AliasEntry = NET.!AliasEntry'SN.'Net.!als.server';'
NET.!AliasEntry = NET.!AliasEntry'RT.'Net.!als.type';'
if NET.!als.type = 'Files',
Then NET.!AliasEntry = NET.!AliasEntry'RP.'Net.!als.path';'
Else NET.!AliasEntry = NET.!AliasEntry'RP.'Net.!als.queue';'
NET.!AliasEntry = NET.!AliasEntry'RU.'Net.!als.maxuses';';
Drop NET.!als.
Return Space(NET.!AliasEntry);
/*-------------------------------------------------------------------*/
GETDOMAIN: /* retrieve an domain entry */
Arg NET.!DomainName
Return RecGet(NET.!MasterBuffer,'UN.'NET.!DomainName);
/*-------------------------------------------------------------------*/
GETFILE: /* get an open file entry */
Arg NET.!filename,NET.!serverentry
if NET.filename = '' Then Return '';
NET.!srvname = GetTag('SN.',NET.!serverentry);
if NET.srvname = '' Then Return '';
if SubStr(NET.!srvname,1,1) <> '\',
Then NET.!srvname = '\\'NET.!srvname;
if NetGetInfo(60,NET.!file,NET.!srvname,NET.!filename) <> 0,
Then Return ''; /* file not found */
NET.!FileEntry = 'RN.'NET.!file.id';'
NET.!FileEntry = NET.!FileEntry'RP.'NET.!file.pathname';'
NET.!FileEntry = NET.!FileEntry'UN.'NET.!file.username';'
Drop NET.!file. NET.!srvname
Return Space(NET.!FileEntry);
/*-------------------------------------------------------------------*/
GETGROUP: /* get a group entry */
Arg NET.!grpname;
if NET.!grpname = '' Then Return ''; /* id required */
if NetGetInfo(70,NET.!grp,NET.!dcid,NET.!grpName) <> 0,
Then Return '';
NET.!groupentry = 'GN.'NET.!grp.Name';FN.'NET.!grp.comment';UL.'
if NetGetInfo(340,NET.!grp,NET.!dcid,NET.!grpName) <> 0,
Then Return ''; /* cannot sample users in this group */
Do NET.!gc = 1 to NET.!grp.0
NET.!groupentry = NET.!groupentry||Value('NET.!grp.'NET.!gc)' '
End;
Drop NET.!grp. NET.!gc
Return Space(NET.!groupentry)';'
/*-------------------------------------------------------------------*/
GETSERVER: /* get an server entry */
Arg NET.!srvname
if NET.!srvname = '' Then Return ''; /* id required */
if SubStr(NET.!srvname,1,1) <> '\',
Then NET.!srvname = '\\'NET.!srvname;
if NetGetInfo(160,Net.!srv,NET.!srvname) <> 0,
Then Return ''; /* cannot find server */
NET.!serverentry = 'SN.'NET.!srv.name';FN.'NET.!srv.comment';'
drop NET.!srv.
Return Space(NET.!serverentry)
/*-------------------------------------------------------------------*/
GETSHARE: /* get an share ressource entry */
Return Space(NET.!shareentry);
/*-------------------------------------------------------------------*/
GETUSER: /* get an user entry from net */
Arg NET.!usrname
if NET.!usrname = '' Then Return ''; /* id required */
If NetGetInfo(280,NET.!usr,NET.!dcid,NET.!usrname) <> 0,
Then Return '';
Call NetGetInfo 330,NET.!grp,NET.!dcid,NET.!usrName
NET.!userentry = 'UN.'NET.!usr.name';'
NET.!userentry = NET.!userentry'FN.'NET.!usr.full_name';'
NET.!userentry = NET.!userentry'OP.'SubStr(NET.!usr.priv,1,1)';'
NET.!userentry = NET.!userentry'PW.'NET.GetPW(NET.!usrname)';'
NET.!userentry = NET.!userentry'AF.'NET.!usr.flags';' /* account flags */
NET.!userentry = NET.!userentry'LL.'NET.Landate(NET.!usr.last_logon)';' /* last logon */
if NET.!usr.comment <> '-none-',
Then NET.!userentry = NET.!userentry||NET.!usr.comment
Else NET.!userentry = NET.!userentry'PO.;AC.;AS.;HD.;';
if SubStr(Reverse(NET.!userentry),1,1) <> ';',
Then NET.!userentry = NET.!userentry';' /* add a delimiter */
if NET.!usr.home_dir <> '-none-',
Then NET.!userentry = NET.!userentry'FS.'NET.!usr.home_dir';'
Else NET.!userentry = NET.!userentry'FS.;'
if Space(NET.!usr.max_storage) <> 'No Limit',
Then NET.!userentry = NET.!userentry'WS.'NET.!usr.max_storage';'
Else NET.!userentry = NET.!userentry'WS.;'
NET.!userentry = NET.!userentry'GL.';
Do NET.!gc = 1 to NET.!grp.0
NET.!userentry = NET.!userentry||Value('NET.!grp.'NET.!gc)' '
End;
Drop NET.!usr. NET.!grp. NET.!gc
Return Space(NET.!userentry)';'
/*-------------------------------------------------------------------*/
ID: /* identify myself */
if NetGetInfo(350,NET.!my,'') <> 0,
Then Return ''; /* cannot identify myself */
if NET.!my.username = '' Then Return '';
Parse Var NET.!my.computername '\\'NET.!my.hostid
NET.!dcid = SetDomain(NET.!my.logon_domain);
NET.!userid = Space(NET.!my.username'@'NET.!my.hostid'.'NET.!my.logon_domain' via 'NET.!dcid);
drop NET.!my.
Return NET.!userid
/*-------------------------------------------------------------------*/
INIUSER: /* initialize DCDB for user */
Parse Arg NET.!userentry,DCDBinit
/* init settings */
NET.!usr.name = GetTag('UN.',NET.!userentry);
if DCDBinit = '',/* init DCDB ? */
Then Do; /* yes */
NET.!errcode = NetMisc(720,NET.!usr.name,NET.!dcid)
if NET.!errcode <> 0 Then Return NET.!errcode /* cannot init DCDB */
End; /* if DCDBinit */
/* however, init profiles here */
Call Net.Profile NET.!userentry,'profile.bat';
Call Net.Profile NET.!userentry,'profile.cmd';
drop NET.!usr.
Return 0;
/*-------------------------------------------------------------------*/
LSTALIAS: /* list LAN aliases */
if NetEnumerate(20,NET.!als,NET.!dcid) = 0,
Then Return '';
NET.!AliasList = NET.!als.0';' /* no of entries */
Do NET.!ac = 1 to NET.!als.0
NET.!AliasList = NET.!AliasList||Value('NET.!als.'NET.!ac)' '
End; /* do ac */
Drop NET.als. ac
Return Space(NET.!AliasList)
/*-------------------------------------------------------------------*/
LSTFILE: /* get a list of open files on a particular server */
Arg NET.!serverentry,NET.!path
NET.!srvname = GetTag('SN.',NET.!serverentry);
if SubStr(NET.!srvname,1,1) <> '\',
Then NET.!srvname = '\\'NET.!srvname;
if NetEnumerate(60,NET.!files,NET.!srvname,NET.!path) <> 0,
Then Return ''; /* cannot retrieve open files */
NET.!filelist = Net.!files.count';'
Do NET.!fc = 1 to NET.!files.count
NET.!filelist = NET.!filelist||Value('NET.!files.'NET.!fc'.id')' '
End;
Drop NET.!files. NET.!fc
Return Space(NET.!filelist);
/*-------------------------------------------------------------------*/
LSTSERVER: /* get a list of all servers in this domain */
if NetEnumerate(160,NET.!srv,NET.!dcid,-1) <> 0,
Then Return ''; /* cannot use LAN */
NET.!serverlist = NET.!srv.0';'
Do NET.!sc = 1 to NET.!srv.0
NET.!serverlist = NET.!serverlist||Value('NET.!srv.'NET.!sc)' '
End;
Drop NET.!srv. NET.!sc
Return Space(NET.!serverlist);
/*-------------------------------------------------------------------*/
LSTUSER: /* get a list of all user ids starting with N of users */
if NetEnumerate(280,NET.!usr,NET.!dcid) <> 0,
Then Return ''; /* error condition */
NET.!userlist = NET.!usr.0';';
Do NET.!uc = 1 to NET.!usr.0
NET.!userlist = NET.!userlist||Value('NET.!usr.'NET.!uc)' '
End;
Drop NET.!usr. NET.!uc
Return Space(NET.!userlist);
/*-------------------------------------------------------------------*/
MODUSER: /* replace a particular user tag entry in the net */
Parse Arg NET.!TagID,NET.!userentry;
NET.!uid = GetTag('UN.',NET.!userentry); /* parse user id */
Select
When NET.!TagID = 'AF.',
Then Return NetSetInfo(280,'flags',GetTag('AF.',NET.!userentry),NET.!dcid,NET.!uid);
When NET.!TagID = 'OP.',
Then Return NetSetInfo(280,'priv',NET.Privilege(GetTag('OP.',NET.!userentry)),NET.!dcid,NET.!uid);
When NET.!TagID = 'FN.',
Then Return NetSetInfo(280,'full_name',GetTag('FN.',NET.!userentry),NET.!dcid,NET.!uid);
When NET.!TagID = 'FS.',
Then Return NetSetInfo(280,'home_dir',GetTag('FS.',NET.!userentry),NET.!dcid,NET.!uid);
When NET.!TagID = 'WS.',
Then Return NetSetInfo(280,'max_storage',GetTag('WS.',NET.!userentry),NET.!dcid,NET.!uid);
When NET.!TagID = 'PW.',
Then if Pos(':',GetTag('PW.',NET.!userentry)) = 0,
Then Return NetSetInfo(280,'password',GetTag('PW.',NET.!userentry),NET.!dcid,NET.!uid);
Else Return Net.setpw(GetTag('PW.',NET.!userentry));
When NET.!TagID = 'PO.',
Then Return NetSetInfo(280,'comment',Net.Comment(NET.!userentry),NET.!dcid,NET.!uid);
When NET.!TagID = 'AC.',
Then Return NetSetInfo(280,'comment',Net.Comment(NET.!userentry),NET.!dcid,NET.!uid);
When NET.!TagID = 'AS.',
Then Return NetSetInfo(280,'comment',Net.Comment(NET.!userentry),NET.!dcid,NET.!uid);
When NET.!TagID = 'HD.',
Then Return NetSetInfo(280,'comment',Net.Comment(NET.!userentry),NET.!dcid,NET.!uid);
When NET.!TagID = 'GL.',
Then Do;
NET.!grplist = GetTag('GL.',NET.!userentry);
NET.!gc = 0;
Do While NET.!grplist <> ''
Parse Value Space(NET.!grplist) with NET.!grpname' 'NET.!grplist
if NET.!grpname = '' Then Leave;
if NET.!grpname = 'USERS' Then Iterate; /* system default */
NET.!gc = NET.!gc + 1;
Call Value 'NET.!grp.'NET.!gc'.name',Space(NET.!grpname)
End;
NET.!grp.count = NET.!gc;
Drop NET.!grplist NET.!gc
Return NetSetInfo(330,NET.!grp,NET.!dcid,NET.!uid);
End;
OtherWise Return 1; /* unknown tagname */
End; /* select */
Return 0; /* to be safe */
/*-------------------------------------------------------------------*/
SETDOMAIN: /* identify domain controller of domain xy */
Arg DomainName
Parse Value NetMisc(510,DomainName,''),
with ErrCode NET.!dcid
Return NET.!dcid; /* empty if erroneous */
/*-------------------------------------------------------------------*/
SETFILES: /* modify a home file set entry */
Parse Arg NET.!userentry
Return Space(NET.!userentry)
/*-------------------------------------------------------------------*/
SETHOME: /* set home file set and init access */
/* return codes:
0 - home files defined and set
1 - home files rights undefined (no dir entry)
x - cannot create/modify/apply
*/
Parse Arg NET.!userentry
Parse Value GetTag('FS.',NET.!userentry),
with ':\'NET.!srv'\'NET.!res
if NET.!srv = '' Then Return 1; /* no dir entry */
NET.!srv = '\\'NET.!srv;
NET.!res = translate(NET.!res,':','$'); /* replace $ by : */
NET.!acl.audit = 'N'; /* no audit required */
NET.!acl.count = 1; /* only this user */
NET.!acl.1.ugname = GetTag('UN.',NET.!userentry); /* this user */
NET.!acl.1.access = 'RWCXDAP'; /* set all */
ErrCode = NetAdd(10,NET.!acl,NET.!srv,NET.!res); /* try to create one */
if ErrCode <> 0, /* cannot create */
Then ErrCode = NetSetInfo(10,NET.!acl,NET.!srv,NET.!res); /* try to modify */
if ErrCode = 0, /* is modified, now apply */
Then ErrCode = NetMisc(520,NET.!acl,NET.!srv,NET.!res); /* apply to SDs */
Drop NET.!srv NET.!res NET.!acl.
Return ErrCode
/*-------------------------------------------------------------------*/
SETUSER: /* replace an user entry completely */
Parse Arg NET.!userentry
Call ModUser 'OP.',NET.!userentry; /* replace privilege level */
Call ModUser 'FN.',NET.!userentry; /* replace full name */
Call ModUser 'AF.',NET.!userentry; /* replace flags */
Call ModUser 'PO.',NET.!userentry; /* replace cc:mail entry */
Call ModUser 'AC.',NET.!userentry; /* replace account entry */
Call ModUser 'AS.',NET.!userentry; /* replace asia entry */
Call ModUser 'HD.',NET.!userentry; /* replace home domain */
Call ModUser 'FS.',NET.!userentry; /* replace home fileset */
Call ModUser 'WS.',NET.!userentry; /* replace max storage */
Call ModUser 'GL.',NET.!userentry; /* replace grouplist */
Call ModUser 'PW.',NET.!userentry; /* replace passowrd */
Return 0;
/*-------------------------------------------------------------------*/
SHOUSER: /* sho data from NET.!userentry */
Parse Arg NET.!userentry
Call Info '------------'
Call Info 'on DC 'NET.!DCID
Call Info 'Net Name 'GetTag('UN.',NET.!userentry);
Call Info 'Full Name 'GetTag('FN.',NET.!userentry);
Call Info 'Password 'GetTag('PW.',NET.!userentry);
Call Info 'Privilege 'NET.Privilege(GetTag('OP.',NET.!userentry));
Call Info 'User Flags 'GetTag('AF.',NET.!userentry);
Call Info 'Home Domain 'GetTag('HD.',NET.!userentry);
Call Info 'Post Office 'GetTag('PO.',NET.!userentry);
Call Info 'Account 'GetTag('AC.',NET.!userentry);
Call Info 'last logon 'GetTag('LL.',NET.!userentry);
Call Info 'ASIA entry 'GetTag('AS.',NET.!userentry);
Call Info 'Group List 'GetTag('GL.',NET.!userentry);
Call Info 'Home Files 'GetTag('FS.',NET.!userentry);
Call Info '------------'
Return 0;
/*-------------------------------------------------------------------*/
/* internal functions here */
/*-------------------------------------------------------------------*/
NET.Landate: Procedure /* compute last login date to yyddd */
Arg NET.!date
if NET.!date = 'UNKNOWN' Then Return ''; /* empty date */
Parse Value Translate(NET.!date,' ','0a'x) with . mm dd . yy .
if yy//4 = 0, /* leap year ? */
Then !feb = 29; /* yes */
Else !feb = 28; /* no */
!MJulian = '00 31 '!feb' 31 30 31 30 31 31 30 31 30 31'
/* yy = SubStr(yy,3,2) */
!MNames = 'JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC';
!Days = 0;
Do !i = 1 to WordPos(mm,!MNames)
!days = !days + Word(!MJulian,!i);
End;
Return yy||Right(!days+dd,3,'0')
/*-------------------------------------------------------------------*/
NET.Comment: /* generate the comment field from NET.!userentry */
Parse Arg NET.!userentry
NET.!usrcomment = 'PO.'GetTag('PO.',NET.!userentry)
NET.!usrcomment = NET.!usrcomment';AC.'GetTag('AC.',NET.!userentry)
NET.!usrcomment = NET.!usrcomment';AS.'GetTag('AS.',NET.!userentry)
NET.!usrcomment = NET.!usrcomment';HD.'GetTag('HD.',NET.!userentry)
Return NET.!usrcomment';'
/*-------------------------------------------------------------------*/
NET.Domains: /* domain map handler */
Parse Arg NET.!domainmap
/* read domain master files */
MyMark = 'DOMAINS';
NET.!MasterBuffer = FileRead(NET.!domainMap);
if NET.!MasterBuffer = '' Then Return ''; /* nothing read */
NET.!MasterEntry = RecGet(NET.!MasterBuffer,'UN.'MyMark);
if NET.!MasterEntry = '' Then Return ''; /* cannot identify */
if GetTag('GL.',NET.!MasterEntry) = '', /* empty domain list ? */
Then Do; /* yes, built one */
NET.!buffer = NET.!MasterBuffer;
Do While NET.!Buffer <> ''
Parse Var NET.!Buffer NET.!Entry '0d0a'x NET.!Buffer
if SubStr(NET.!Entry,1,3) <> 'UN.' Then Iterate;
if GetTag('UN.',NET.!Entry) = MyMark Then Iterate;
NET.!domain = GetTag('GL.',NET.!MasterEntry)' 'GetTag('UN.',NET.!Entry);
NET.!MasterEntry = SetTag('GL.',NET.!domains,NET.!MasterEntry)
End; /* do while */
Drop NET.!domain
End; /* if domains */
Return NET.!MasterEntry;
/*-------------------------------------------------------------------*/
NET.Profile: /* (re-)write profile */
Parse Arg NET.!userentry,NET.!profn
/* profiles here */
NET.!usr.dcdb = NET.!dcid'\admin$\dcdb\users\'GetTag('UN.',NET.!userentry);
Genned = 'REM genned 'Date()' 'Time()' by 'MyID
Mailer = Net.Mailer(GetTag('PO.',NET.!userentry));
/* save current profile */
Call FileWrite NET.!usr.dcdb'\profile.old',FileRead(NET.!usr.dcdb'\'NET.!profn);
NET.!Buffer = FileRead(NET.!usr.dcdb'\'NET.!profn);
if NET.!Buffer = '', /* has data ? */
Then NET.!Buffer = RecSet(NET.!Buffer,,'@ECHO OFF'); /* no, init */
NET.!Buffer = RecSet(NET.!Buffer,'REM genned',Genned);
NET.!Buffer = RecSet(NET.!Buffer,'NET USE S:',NET.Mailer(NET.!poname));
Call FileWrite NET.!usr.dcdb'\'NET.!profn,NET.!Buffer;
Drop NET.!buffer;
Return 0;
/*-------------------------------------------------------------------*/
NET.Mailer: /* retrieve mailer */
Arg NET.!poname
/* actually, simple assignment, hard coded */
if NET.!poname = '' Then Return ''
if NET.!poname = 'CIP' Then Return 'NET USE S: \\cip-srv\CIP'
Return 'NET USE S: \\mail-srv\'Net.!poname;
/*-------------------------------------------------------------------*/
NET.Privilege: Procedure /* generate privilege data */
Arg NET.!Priv
if NET.!Priv = 'U' Then Return 'User';
if NET.!Priv = 'A' Then Return 'Administrator';
if NET.!Priv = 'G' Then Return 'Guest';
Return ''; /* error condition */
/*-------------------------------------------------------------------*/
NET.GETPW: /* retrieve PW from DC */
Arg NET.!uid
if IsFile(NET.!dcid'\admin$\netprog\pwdexp.exe') = '',
Then Return ''; /* no program, fake empty pw */
If NetMisc(710,'pwdexp 'NET.!uid,NET.!dcid,'NET.!Result') <> 0,
Then Return ''; /* program error, fake empty pw */
Parse Var NET.!Result.output Net.!Result.Output '0d0a'x;
Return Space(NET.!Result.output);
/*-------------------------------------------------------------------*/
NET.SETPW: /* set PW from DC */
Arg NET.!pwentry
if IsFile(NET.!dcid'\admin$\netprog\pwdimp.exe') = '',
Then Return ''; /* no program, fake empty pw */
Return NetMisc(710,'pwdimp 'NET.!pwentry,NET.!dcid,'NET.!Result');
/*-------------------------------------------------------------------*
m* MODULE files
* <C> Wolfram Fassbender, wofa@wiwiss.fu-berlin.de
* history:
* 1996/12/06 - 1.0 initial release
* 1997/03/08 - 1.1 added ISDIR, ISFILE functions
* 1997/12/08 - 2.0 renewed RECxxx functions
* 1998/02/08 - 2.1 added SCRATCHFILE function
c* notes:
c* - need REXXUTIL.DLL (from IBM OS/2 REXX)
*-------------------------------------------------------------------*/
FILESINI: /* init module files */
Call RxFuncAdd Sysloadfuncs,rexxutil,sysloadfuncs
Call sysloadfuncs
Return 0;
/*-------------------------------------------------------------------*/
FILESFIN: /* finit module files */
Drop FILES.
Return 0;
/*-------------------------------------------------------------------*/
CDDIR: /* change to dir, make one if not existing */
Parse Arg FILES.!dn
if FILES.!dn = '' Then Return '';
if \isdir(FILES.!dn),
Then Call SysMkDir FILES.!dn;
Call Directory FILES.!dn;
Return Directory();
/*-------------------------------------------------------------------*/
DIRDEL: Procedure /* delete dirtree */
Parse Arg FILES.!dn
Call FileDel FILES.!dn'\*.*'
Call SysFileTree FILES.!dn'\*.*',FILES.!isdir.,'OD';
if FILES.!isdir.0 = 0,
Then Return SysRmDir(FILES.!dn); /* no, one dir */
Do i = 1 to FILES.!isdir.0
Call DirDel(FILES.!isdir.i);
End; /* do i */
Return SysRmDir(FILES.!dn); /* dir removed */
/*-------------------------------------------------------------------*/
DIRGEN: /* make a subdirectory and its rootpath */
Parse Arg FILES.!dn;
if FILES.!dn = '' Then Return ''; /* need dirname */
Select
When Pos('$',FILES.!dn) > 0, /* have UNC ? */
then Do; Parse Var FILES.!dn FILES.!root '$\'FILES.!tree; FILES.!root = FILES.!root'$';end;
When Pos(':',FILES.!dn) > 0, /* have Drive ? */
then Do; Parse Var FILES.!dn FILES.!root ':\'FILES.!tree; FILES.!root = FILES.!root':';end;
OtherWise Do; Parse Var FILES.!dn FILES.!root '\'FILES.!tree; FILES.!root = FILES.!root;end;
End; /* select */
Do While FILES.!tree <> ''
Parse Var FILES.!tree FILES.!ldn'\'FILES.!tree
if FILES.!ldn = '' Then Leave; /* to be safe */
FILES.!root = FILES.!root'\'FILES.!ldn;
if \isdir(FILES.!root),
Then Call SysMkDir FILES.!root;
End;
Return FILES.!dn;
/*-------------------------------------------------------------------*/
FILEDEL: Procedure /* delete file(s) */
Parse Arg FILES.!fn
if Pos('*',Files.!fn) = 0, /* more than one file ? */
Then Return SysFileDelete(FILES.!fn); /* no, one file */
Call SysFileTree FILES.!fn,FILES.!isfile.,'OF','*****','***-*';
if FILES.!isfile.0 = 0 Then Return '';
'@attrib -r * > NUL'; /* to be safe */
Do i = 1 to FILES.!isfile.0
Call SysFileDelete FILES.!isfile.i;
End; /* do i */
Return 0; /* file(s) purged */
/*-------------------------------------------------------------------*/
FILEREAD: /* read a complete file into FILES.!buffer */
Parse Arg FILES.!fn,delflag
if FILES.!fn = '' Then Return '';
Call Stream FILES.!fn,'c','close'; /* before reading */
Parse Value CharIn(FILES.!fn,1,Chars(FILES.!fn)) with FILES.!buffer'1A'x;
Call Stream FILES.!fn,'C','Close';
if delflag <> '' Then Call FileDel FILES.!fn /* delete after read */
Return FILES.!buffer
/*-------------------------------------------------------------------*/
FILEWRITE: /* rewrite a file from FILES.!buffer */
Parse Arg FILES.!fn,FILES.!buffer
if FILES.!fn = '' Then Return '';
Call Stream FILES.!fn,'c','close'; /* before writing */
Call SysFileDelete FILES.!fn /* garantuee complete rewrite */
Call CharOut FILES.!fn,FILES.!buffer'1A'x,1;
Call Stream FILES.!fn,'C','Close';
Return 0;
/*-------------------------------------------------------------------*/
ISDIR: /* is directory ? return true/false */
Parse Arg FILES.!dn
Return IsFile(FILES.!dn) = '' & Stream(FILES.!dn,'c','query size') = 0;
/*-------------------------------------------------------------------*/
ISFILE: /* is file ? return filename if existing otherwise '' */
Parse Arg FILES.!fn
if FILES.!fn = '' Then Return ''; /* not found */
Return Stream(FILES.!fn,'c','Query Exists');
/*-------------------------------------------------------------------*/
RECGET: Procedure /* get 1st record with id from buffer */
Arg FILES.!buffer,FILES.!id /* come in uppercase */
if FILES.!buffer = '' Then Return ''; /* nothing to scan */
Parse Var FILES.!buffer,
FILES.!header (FILES.!id) FILES.!trailer '0d0a'x FILES.!buffer
if FILES.!trailer = '' Then Return ''; /* nothing found */
Parse Value Reverse(FILES.!header),
with FILES.!header'0a'x /* back to crlf */
FILES.!header = Reverse(FILES.!header);
if SubStr(FILES.!header,1,1) = ';', /* is comment ? */
Then Return RecGet(FILES.!buffer,FILES.!id); /*yes, try rest */
Return FILES.!header||FILES.!id||FILES.!trailer; /* got it */
/*-------------------------------------------------------------------*/
RECSET: /* add/ins/del a record */
Arg FILES.!buffer,FILES.!id,FILES.!newrec /* come in uppercase */
if FILES.!buffer = '', /* empty buffer ? */
Then Return FILES.!newrec; /* yes, new record becomes 1st record */
Parse Var FILES.!buffer,
FILES.!header (FILES.!id) FILES.!data '0d0a'x FILES.!trailer
if FILES.!data = '', /* found id ? */
Then if SubStr(FILES.!buffer,Length(FILES.!buffer),1) = '0a'x,
Then Return FILES.!buffer||FILES.!newrec /* no, append */
Else Return FILES.!buffer'0d0a'x||FILES.!newrec /* no, append */
Parse Value Reverse(FILES.!header),
with FILES.!record '0a0d'x /* back to crlf */
FILES.!record = Reverse(FILES.!record);
if SubStr(FILES.!record,1,1) = ';', /* is comment ? */
Then /* yes, retry */ Return FILES.!header||FILES.!id||FILES.!data'0d0a'x||RecSet(FILES.!trailer,FILES.!id,FILES.!newrec);
if FILES.!newrec = '', /* empty new record ? */
Then Return FILES.!header||FILES.!trailer /* yes, delete */
if FILES.!trailer = '', /* has trailer ? */
Then Return FILES.!header||FILES.!newrec /* no, append */
Return FILES.!header||FILES.!newrec'0d0a'x||FILES.!trailer /* replace */
/*-------------------------------------------------------------------*/
SCRATCHFILE: /* return a scratch file name */
Parse Arg FILES.!fn /* template, eg. ??DIR?.??? */
if FILES.!fn = '', /* have template ? */
Then Return SysTempFileName('$$$?????.$$$'); /* no, retry my own */
FILES.!scratchname = SysTempFileName(FILES.!fn);
if FILES.!scratchname <> '', /* got one ? */
Then Return FILES.!scratchName; /* yes, return name */
/*-------------------------------------------------------------------*
m* MODULE TAG
* FILES
*
* <C> Wolfram Fassbender, wofa@wiwiss.fu-berlin.de
* History
* 1996/12/08 - 1.0 initial version, from NET module
* 1997/06/12 - 1.1 added tags for IBM LAN SERVER
* 1997/12/12 - 2.0 completely reprogrammed (stiffened code)
* 1997/12/13 - 2.1 using UPPER CASE (speeding up)
* 1998/03/09 - 2.2 added function COPYTAG
c*
c* Tag Fields as follows
c* - AC.yyddd julian date of ACcount entry
c* - AF.flags Account Flags
c* - AR.rights Access Rights
c* - AS.asia ASia tag
c* - FN.name,name FullName (cc:mail name)
c* - FS.homedef home File Set
c* - GN.groupid GroupName
c* - GL.id id NET.!grouplist
c* - HD.domain Home Domain name
c* - LL.yyyyddd julian date of Last Login entry
c* - OP.privilege user's Operation Privilege
c* - PO.postoffice cc:mail Post Office name
c* - PW.password lan & cc:mail PassWord
c* - RL.res-name Ressource List
c* - RN.res-name Ressource Name
c* - RP.res-path Ressource Path/Queue
c* - RT.res-type Ressource Type (files, serial, printer)
c* - RU.res-users Ressource max Users
c* - SN.serverid ServerName
c* - TH.threshold threshold value
c* - UL.userlist userlist (in a group)
c* - UN.userid lan UserName
c* - WS.nnnn Working Storage of homefileset
c*
c* userentry record
c* - UN.;FN.;OP.;PW.;AF.;LL.;PO.;AC.;AS.;HD.;FS.;WS.;GL.;RL.;
c*
c* groupentry record
c* - GN.;FN.;FS.;PO.;AC.;WS.;FS.;WS.;UL.;
c*
c* serverentry record
c* - SN.;FN.;
c*
c* ressourceentry record
c* - RN.;FN.;SN.;RT.;RP.;RU.;
c*
c* filentry record
c* - RN.;RP.;UN.;
c*
c* Implementation Notes
*-------------------------------------------------------------------*/
TAGINI: /* initialize TAG module */
/* init global vars */
TAG.!List = 'AC. AF. AN. AR. AS.';
TAG.!List = TAG.!List' FL. FN. FS.'; /* note the starting blank */
TAG.!List = TAG.!List' GN. GL.';
TAG.!List = TAG.!List' HD.';
TAG.!List = TAG.!List' LL.';
TAG.!List = TAG.!List' OP.';
TAG.!List = TAG.!List' PO. PW.';
TAG.!List = TAG.!List' RL. RN. RP. RT. RU.';
TAG.!List = TAG.!List' SL. SN.';
TAG.!List = TAG.!List' TH.';
TAG.!List = TAG.!List' UL. UN.';
TAG.!List = TAG.!List' WS.';
Return 0;
/*-------------------------------------------------------------------*/
TAGLIST: /* return a list of valid tags */
Return TAG.!List;
/*-------------------------------------------------------------------*/
TAGFIN: /* finalize TAG module */
Drop TAG.
Return 0;
/*-------------------------------------------------------------------*/
COPYTAG: /* copy a tag value from <source> to <sink> */
Arg TAG.!name,TAG.!source,TAG.!sink
Return SetTag(TAG.!name,GetTag(TAG.!name,TAG.!source),TAG.!sink);
/*-------------------------------------------------------------------*/
GETTAG: Procedure /* get tag data from an user entry */
Parse Arg TAG.!name,TAG.!entry
if TAG.!entry = '' Then Return ''; /* empty tag */
Parse Var TAG.!entry (TAG.!name) TAG.!data';'
if TAG.!data = '-none-' Then TAG.!data = '';
Return Space(TAG.!data);
/*-------------------------------------------------------------------*/
SETTAG: /* set tag in an user entry */
Parse Arg TAG.!name,TAG.!newdata,TAG.!entry
if WordPos(TAG.!name,TAG.!List) = 0,
Then Return TAG.!entry; /* Tagname unknown */
TAG.!newdata = Strip(Translate(TAG.!newdata,' ',';'));
Parse Var TAG.!entry TAG.!header (TAG.!name) TAG.!data';'TAG.!trailer;
Return TAG.!header||TAG.!name||TAG.!newdata';'||TAG.!trailer; /* yes, rep */
/*-------------------------------------------------------------------*
m* MODULE prolog
* <C> Wolfram Fassbender, wofa@wiwiss.fu-berlin.de
* history:
* 1996/08/10 - 1.0 initial release
* 1996/08/16 - 1.1 added NIRVANA option
* 1996/08/20 - 1.2 initial LOGFILE setting becomes NUL
* 1997/01/12 - 1.3 new helper (see MAIN MODULE)
* 1997/05/12 - 1.4 new SYNTAX error exit (shortened)
* 1997/12/06 - 1.5 calls user FINI before dying
* 1998/03/16 - 1.6 set LOGfilename to current date
* notes:
* I wrote a MODGEN procedure which adds this PROLOG automatically
*-------------------------------------------------------------------*/
PROLOG: /* starting here */
Signal on SYNTAX;
Signal on HALT; /* user interrupt exit */
Parse Source OSName Environment Callee
If Pos('INSTORE',Translate(Callee)) = 0,
Then; Do;
Parse Value Reverse(Callee),
with RealType'.'RealName'\'LocalPath;
RealType = Reverse(RealType);
RealName = Reverse(RealName);
LocalPath = Reverse(LocalPath);
End;
Else LocalPath = Directory();
Parse Arg ParmList'/'OptList
ParmList = Space(ParmList); OptList = Space(OptList);
/* initialize constants */
True = 1; False = 0; /* boolean operands */
/* initialize defaults */
Verbose = False; /* quiet mode */
Nirvana = False; /* off to caller */
Call Time R;
LogFile = 'NUL'; /* log to nirvana */
/* standard helper */
If ParmList = '?' Then Exit Help();
If ParmList = '-?' Then Exit Help();
/* option parser */
Call UserOpt; /* initialize user options */
Do While OptList <> ''
Parse Var OptList Option'/'OptList
Call OptIni Option
End; /* do while */
Call Info 'running as 'callee
Return Main(0); /* off to caller */
/*-------------------------------------------------------------------*/
OPTINI: /* set option */
Parse Arg Option
Parse Var Option OptName':'OptValue
OptName = Translate(Space(OptName,0));
Select
When Abbrev('?' ,OptName,1) Then Return Help();
When Abbrev('LOGGING',OptName,1) Then LogFile = LocalPath'\'Date(s)'.log';
When Abbrev('VERBOSE',OptName,1) Then Verbose = True;
When Abbrev('SILENT' ,OptName,1) Then Verbose = False;
When Abbrev('NIRVANA',OptName,1) Then Nirvana = True;
OtherWise Return UserOpt(Optname,OptValue);
End; /* select */
if LogFile <> 'NUL',
Then Verbose = True; /* force chat */
Return 0; /* option set */
/*-------------------------------------------------------------------*/
INFO: /* info with CRLF */
Parse Arg InfoMsg
if \Verbose Then Return 0; /* silent running */
InfoMsg = Date(o)' 'Time()': 'InfoMsg;
if SubStr(Reverse(InfoMsg),1,1) = '0d'x,
Then Return CharOut(,InfoMsg); /* tell it without LF */
Else Call LineOut ,'0d'x||InfoMsg; /* tell it */
If LogFile <> 'NUL',
Then Do;
Call LineOut LogFile,InfoMsg; /* append to log */
Call Stream LogFile,'c','Close'; /* close */
End;
Return 0;
/*-------------------------------------------------------------------*/
HELP: /* help exit */
h = 1;
Do While SubStr(SourceLine(h),1,2) <> '.*'; /* skip to .* comments */
h = h + 1;
End; /* for */
Say '.* usage: ';
Say '.* 'Callee' ParmList /OptList'
Do While SubStr(SourceLine(h),1,2) = '.*' ; /* this is help */
Say SourceLine(h);
h = h + 1;
End; /* for */
Drop h;
Return Die(1);
/*-------------------------------------------------------------------*/
LOWER: /* return mixed-case input in lowercase */
Arg uppercase /* translate here */
lo = 'abcdefghijklmnopqrstuvwxyz';
Return Translate(uppercase,lo,Translate(lo));
/*-------------------------------------------------------------------*/
SYNTAX: /* REXX error exit */
Say 'REXX - Error : 'ErrorText(RC)
Say 'in procedure : 'Callee;
Say 'in line : 'Sigl;
Say 'Statement is : 'Space(SourceLine(Sigl));
Say 'Environment : 'OSName' 'Environment;
/* and off */
Nirvana = False; /* back to caller, is crash */
Return Die(2); /* anyway */
/*-------------------------------------------------------------------*/
CRASH: /* exit */
Parse Arg ErrCode,ErrMsg
Verbose = True; /* force */
Call Info 'Crash- 'ErrMsg; /* tell it */
Nirvana = False; /* back to caller, is crash */
Return DIE(ErrCode); /* anyway */
/*-------------------------------------------------------------------*/
HALT: /* interrupt exit (ctrl-c) */
Call Info 'User interrupted...';
Return Epilog(2);
/*-------------------------------------------------------------------*/
EPILOG: /* shutdown exit */
Arg ErrCode
Call Info 'exiting with RC 'ErrCode
Return Die(ErrCode);
/*-------------------------------------------------------------------*/
DIE: /* panic exit */
Arg ErrCode
Call Fini ErrCode; /* user finalizing exit, called in any condition */
If LogFile <> 'NUL',
Then Call Stream LogFile,'c','close';
if Nirvana Then '@Exit'; /* off into nirvana */
if Environment = 'COMMAND' Then Exit ErrCode; /* off to OS */
Drop Environment
Return ErrCode; /* return to caller */